package com.eunion.common.util;

import java.awt.image.BufferedImage;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.commons.io.FileExistsException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.SerializationException;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.ConstructorUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * 提取comm-lang包中的常用工具类
 */
public class CommUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(CommUtils.class);

    private static final String DEFAULT_URL_ENCODING = "UTF-8";

    private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();

    /** Datetime yyyy-MM-dd HH:mm:ss . */
    public static final String FORMAT_DATETIME = "yyyy-MM-dd HH:mm:ss";

    /** Datetime yyyyMMdd HH:mm:ss . */
    public static final String FORMAT_DATETIME_SEARCH = "yyyyMMdd HH:mm:ss";

    /** 缺省的日期时间格式 */
    public static final String FORMAT_DATETIME_SIMPLE = "yyyy-M-d HH:mm:ss";

    /** Datetime all yyyyMMddHHmmssS . */
    public static final String FORMAT_DATETIME_ALL = "yyyyMMddHHmmssS";

    /** yyyyMMddHHmmssSSS */
    public static final String FORMAT_DATETIME_ALL_SSS = "yyyyMMddHHmmssSSS";

    /** Date yyyyMMdd. */
    public static final String FORMAT_DATE_COMPACT = "yyyyMMdd";

    /** Date yyyy-MM-dd . */
    public static final String FORMAT_DATE = "yyyy-MM-dd";

    /** Date monty yyyyM. */
    public static final String FORMAT_DATE_M = "yyyyM";

    /** yyyy-M-d. */
    public static final String FORMAT_DATE_SIMPLE = "yyyy-M-d";

    /** 日期格式 yyyy-MM-dd HH. */
    public static final String FORMAT_DATE_HH = "yyyy-MM-dd HH";

    /** 日期格式 yyyy_MM_dd. */
    public static final String FORMAT_DATE_LOW = "yyyy_MM_dd";

    /** 日期格式 yyyy-MM. */
    public static final String FORMAT_DATE_YEARMONTH = "yyyy-MM";

    /** 日期格式 yyyy.MM.dd. */
    public static final String FORMAT_DATE_DOT = "yyyy.MM.dd";

    /** 日期格式 yyyy.MM.dd.HH. */
    public static final String FORMAT_DATE_DOTHOUR = "yyyy.MM.dd.HH";

    /** 日期格式yyyyMMddHH . */
    public static final String FORMAT_DATA_PDF = "yyyyMMddHH";

    /** HH:mm:ss . */
    public static final String FORMAT_TIME = "HH:mm:ss";

    /**
     * 写一个默认的私有的构造函数，禁止用过通过构造对象来调用方法
     */
    private CommUtils() {}

    /**
     * <p> 检验是否为空 </p>
     * @param obj Collection，Map，Array,CharSequence,...
     * @return 为空返回 TRUE 否则返回 FALSE <p>例子:</p> <ul> <li> StringUtil.isEmpty(null); <p>返回true</p> </li> <li> StringUtil.isEmpty(new
     *         HashMap<Object,Object>()); <p>返回true</p> </li> <li> StringUtil.isEmpty(new List<String>()); <p>返回true</p> </li> <li>
     *         StringUtil.isEmpty(""); <p>返回true</p> </li> <li> StringUtil.isEmpty(new String()); <p>返回true</p> </li> </ul>
     */
    @SuppressWarnings({"rawtypes"})
    public static boolean isEmpty(Object obj) {
        if (obj == null) {
            return true;
        }
        if (obj instanceof Collection) {
            return ((Collection) obj).isEmpty();
        } else if (obj instanceof Map) {
            return ((Map) obj).isEmpty();
        } else if (obj.getClass().isArray()) {
            return ((Object[]) obj).length == 0;
        } else if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length() == 0;
        } else if (obj instanceof Date) {
            return false;
        } else if (obj instanceof Number) {
            return false;
        } else {
            throw new IllegalArgumentException("检验空参数有误：" + obj.getClass());
        }
    }

    /**
     * 判断对象不为空
     * @param cs Collection，Map，Array,CharSequence,...
     * @return 为空返回FALSE，否则放回TRUE
     */
    public static boolean isNotEmpty(Object cs) {
        return !isEmpty(cs);
    }

    /**
     * 将字符串时间转换成java.util.Date类型
     * @param str 要转换的字符
     * @param format 时间格式
     * @return 如果转换失败，返回null
     */
    public static Date string2Date(String str, String format) {
        // 定义日期/时间格式
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date date;
        try {
            // 转换日期/时间格式
            date = sdf.parse(str);

            if (!str.equals(sdf.format(date))) {
                date = null;
            }
        } catch (ParseException e) {
            date = null;
        }
        return date;
    }

    /**
     * 将java bean对象转换成map对象
     * @param bean
     * @return
     * @throws IntrospectionException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * 
     *             <pre>
     *例子:
     *User user=new User("张三",33);
     *Map map=MapUtil.convertBean(user);
     *String name=(String) map.get("name");
     *             </pre>
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static Map convertBean(Object bean)
        throws IntrospectionException, IllegalAccessException, InvocationTargetException {
        Class type = bean.getClass();
        Map returnMap = new HashMap();
        BeanInfo beanInfo = Introspector.getBeanInfo(type);

        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (int i = 0; i < propertyDescriptors.length; i++ ) {
            PropertyDescriptor descriptor = propertyDescriptors[i];
            String propertyName = descriptor.getName();
            if (!propertyName.equals("class")) {
                Method readMethod = descriptor.getReadMethod();
                Object result = readMethod.invoke(bean, new Object[0]);
                if (result != null) {
                    returnMap.put(propertyName, result);
                } else {
                    returnMap.put(propertyName, "");
                }
            }
        }
        return returnMap;
    }

    /**
     * 将map转换成bean
     * @param map map对象
     * @param cls 要转换的对象
     * @return 当成功时返回 cls的对象，失败时返回null。
     */
    public static <T> T convertMap2Bean(Map<String, Object> map, Class<T> cls) {
        try {
            T obj = ConstructorUtils.invokeConstructor(cls, new Object[] {});
            Set<String> keys = map.keySet();
            for (String key : keys) {
                // 获取值
                Object objs = map.get(key);
                FieldUtils.writeDeclaredField(obj, key, objs, true);
            }
            return obj;
        } catch (Exception e) {
            LOGGER.error("转换出现错误", e.getMessage());
            return null;
        }
    }

    /**
     * 获取一个32位UUID不包含- 如 fbe1b750a9f5497681bcc3dcabfa0af3
     * @return
     */
    public static String getRandomUUID32() {
        return java.util.UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * 获取一个36位UUID， 如c20287dd-dd7d-485b-880f-2d8d0364a669
     * @return
     */
    public static String getRandomUUID36() {
        return java.util.UUID.randomUUID().toString();
    }

    /**
     * <p>根据模式格式化日期</p>
     * @param calendar 要格式化的日期，不能为null
     * @param pattern 要格式化的模式，不能为null
     * @return 返回的日期字符串
     * @see FastDateFormat#format(Calendar)
     * @since 2.4
     */
    public static String format(final Calendar calendar, final String pattern) {
        return DateFormatUtils.format(calendar, pattern);
    }

    /**
     * <p>通过模式格式化一个日期对象</p>
     * @param date 要格式化的日期，不能为空
     * @param pattern 要格式化的模式，不能为null
     * @return 返回的日期字符串
     */
    public static String format(final Date date, final String pattern) {
        return DateFormatUtils.format(date, pattern);
    }

    /**
     * <p>根据模式格式化一个日期或时间</p>
     * @param millis 要格式化的毫秒数
     * @param pattern 要格式化的模式，不能为null
     * @return 返回的日期字符串
     */
    public static String format(final long millis, final String pattern) {
        return DateFormatUtils.format(millis, pattern);
    }

    /**
     * 创建一个32位的md5字符串
     * @param data 要加密的字符串
     * @return 返回的md5字符串
     */
    public static String md5Hex(final String data) {
        return DigestUtils.md5Hex(data);
    }

    /**
     * 计算字节数组的md5字符串
     * @param data 要计算的字节数组
     * @return MD5字符串，长度是32位
     */
    public static String md5Hex(final byte[] data) {
        return DigestUtils.md5Hex(data);
    }

    /**
     * 计算字节数组的md5值
     * @param data 要计算的字节数组
     * @return MD5 digest
     */
    public static byte[] md5(final byte[] data) {
        return DigestUtils.md5(data);
    }

    /**
     * 计算一个流中数据的md5值
     * @param data 要计算的流
     * @return MD5 digest
     * @throws IOException On error reading from the stream
     * @since 1.4
     */
    public static byte[] md5(final InputStream data)
        throws IOException {
        return DigestUtils.md5(data);
    }

    /**
     * 以项目的跟目录为相对路径获取配置文件对象
     * @param 文件名(包括路径)
     * @return 配置文件对象
     * @throws IOException
     */
    public static Properties loadProperty(String name)
        throws IOException {
        Properties props = new Properties();
        InputStream file = new FileInputStream(CommUtils.class.getClassLoader().getResource(name).getFile());
        props.load(file);
        return props;
    }

    /**
     * 计算一个字符串的md5
     * @param data 要计算的字符串,字符的编码是utf-8
     * @return MD5 digest
     */
    public static byte[] md5(final String data) {
        return DigestUtils.md5(data);
    }

    /**
     * 计算一个流中数据的md5
     * @param data 输入流
     * @return 计算后的md5字符串
     * @throws IOException On error reading from the stream
     * @since 1.4
     */
    public static String md5Hex(final InputStream data)
        throws IOException {
        return DigestUtils.md5Hex(data);
    }

    /**
     * 对数据进行base64编码
     * @param binaryData 要编码的数据
     * @return String 经过base64加密的字符串
     */
    public static String encodeBase64String(final byte[] binaryData) {
        return Base64.encodeBase64String(binaryData);
    }

    /**
     * 解码base64字符串
     * @param 要解码的base64字符串
     * @return 解码后的数据数组
     * @since 1.4
     */
    public static byte[] decodeBase64(final String base64String) {
        return Base64.decodeBase64(base64String);
    }

    /**
     * 将byte数组转换成字符串
     * @param input
     * @return 转换后的字符串
     */
    public static String encodeHex(byte[] input) {
        return Hex.encodeHexString(input);
    }

    /**
     * 将字符串转换成byte数组
     * @param input
     * @return byte数组
     * @throws Exception 转换失败抛出异常
     */
    public static byte[] decodeHex(String input)
        throws Exception {
        try {
            return Hex.decodeHex(input.toCharArray());
        } catch (Exception e) {
            throw new Exception(e);
        }

    }

    /**
     * Base64编码, URL安全(将Base64中的URL非法字符'+'和'/'转为'-'和'_', 见RFC3548).
     */
    public static String encodeUrlSafeBase64(byte[] input) {
        return Base64.encodeBase64URLSafeString(input);
    }

    /**
     * Base62编码。
     */
    public static String encodeBase62(byte[] input) {
        char[] chars = new char[input.length];
        for (int i = 0; i < input.length; i++ ) {
            chars[i] = BASE62[((input[i] & 0xFF) % BASE62.length)];
        }
        return new String(chars);
    }

    /***
     * 将html转码成字符串(只转换特殊字符)
     * @param html
     * @return
     */
    public static String escapeHtml(String html) {
        return StringEscapeUtils.escapeHtml4(html);
    }

    /**
     * 解码字符串
     * @param htmlEscaped
     * @return
     */
    public static String unescapeHtml(String htmlEscaped) {
        return StringEscapeUtils.unescapeHtml4(htmlEscaped);
    }

    /**
     * 将xml中的特殊字符串转码
     * @param xml
     * @return
     */
    public static String escapeXml(String xml) {
        return StringEscapeUtils.escapeXml11(xml);
    }

    /**
     * Xml 解码.
     */
    public static String unescapeXml(String xmlEscaped) {
        return StringEscapeUtils.unescapeXml(xmlEscaped);
    }

    /**
     * URL 编码, Encode默认为UTF-8.
     * @throws Exception
     */
    public static String urlEncode(String part)
        throws Exception {
        try {
            return URLEncoder.encode(part, DEFAULT_URL_ENCODING);
        } catch (UnsupportedEncodingException e) {
            throw new Exception(e);
        }
    }

    /**
     * URL 解码, Encode默认为UTF-8.
     * @throws Exception
     */
    public static String urlDecode(String part)
        throws Exception {

        try {
            return URLDecoder.decode(part, DEFAULT_URL_ENCODING);
        } catch (UnsupportedEncodingException e) {
            throw new Exception(e);
        }
    }

    /**
     * <p> 从字节数组中反序列化一个对象 </p>
     * @param <T> 要序列化对象的类型
     * @param objectData 要反序列化的对象字节数组，不能为null
     * @return 序列化的对象
     * @throws IllegalArgumentException 如果 {@code objectData} 是 {@code null}
     * @throws SerializationException (runtime) 如果序列化失败
     */
    public static <T> T deserialize(final byte[] objectData) {
        return SerializationUtils.deserialize(objectData);
    }

    /**
     * <p> 从一个输入流中反序列化一个对象 </p>
     * @param <T> 要反序列化对象的类型
     * @param inputStream 序列化对象的流
     * @return 反序列化的对象
     * @throws IllegalArgumentException 如果 {@code inputStream} 是 {@code null}
     * @throws SerializationException (runtime) 如果反序列化失败
     */
    public static <T> T deserialize(final InputStream inputStream) {
        return SerializationUtils.deserialize(inputStream);
    }

    /**
     * <p>序列化一个对象到字节数组中</p>
     * @param obj 要序列化的对象
     * @return 序列化成功的字节数组
     * @throws SerializationException (runtime) 如果序列化失败
     */
    public static byte[] serialize(final Serializable obj) {
        return SerializationUtils.serialize(obj);
    }

    /**
     * <p>序列化一个对象到输出流中</p>
     * @param obj 要序列化的对象，不能为空
     * @param outputStream 要写入的流，不能为空
     * @throws IllegalArgumentException 如果 {@code outputStream} 是 {@code null}
     * @throws SerializationException (runtime) 如果序列化失败
     */
    public static void serialize(final Serializable obj, final OutputStream outputStream) {
        SerializationUtils.serialize(obj, outputStream);
    }

    /**
     * <p> 创建一个随机的字节数组 </p>
     * @param count 数组的大小
     * @return 随机的字节数组
     * @throws IllegalArgumentException 如果 {@code count} 是负数
     */
    public static byte[] nextBytes(int count) {
        return RandomUtils.nextBytes(count);
    }

    /**
     * <p> 返回一个指定范围的随机的double数据 </p>
     * @param startInclusive 最小值，但是不能为负数
     * @param endInclusive 最大值（包含）
     * @throws IllegalArgumentException 如果 {@code startInclusive > endInclusive} 或者如果 {@code startInclusive} 是负数
     * @return the random double
     */
    public static double nextDouble(double startInclusive, double endInclusive) {
        return RandomUtils.nextDouble(startInclusive, endInclusive);
    }

    /**
     * <p> 返回一个指定范围的随机的float数据 </p>
     * @param startInclusive 最小值，但是不能为负数
     * @param endInclusive 最大值（包含）
     * @throws IllegalArgumentException 如果 {@code startInclusive > endInclusive} 或者 如果 {@code startInclusive} 是负数
     * @return the random float
     */
    public static float nextFloat(float startInclusive, float endInclusive) {
        return RandomUtils.nextFloat(startInclusive, endInclusive);
    }

    /**
     * <p> 返回一个指定范围的随机的int数据 </p>
     * @param startInclusive 最小值，但是不能为负数
     * @param endExclusive 最大值（包含）
     * @throws IllegalArgumentException 如果 {@code startInclusive > endExclusive} 或者 如果 {@code startInclusive} 是负数
     * @return the random integer
     */
    public static int nextInt(int startInclusive, int endExclusive) {
        return RandomUtils.nextInt(startInclusive, endExclusive);
    }

    /**
     * <p> 返回一个指定范围的随机的long数据 </p>
     * @param startInclusive 最小值，但是不能为负数
     * @param endExclusive 最大值（包含）
     * @throws IllegalArgumentException 如果 {@code startInclusive > endExclusive} 或者 如果 {@code startInclusive} 是负数
     * @return the random long
     */
    public static long nextLong(long startInclusive, long endExclusive) {
        return RandomUtils.nextLong(startInclusive, endExclusive);
    }

    /**
     * <p>从指定字符串中创建一个随机的字符串，长度是count</p>
     * 
     * <pre>
     *列入在abcdefgh中创建一个字符串
     *String result = random(20,"abcdefgh");
     * </pre>
     * 
     * @param count 要创建字符串的长度
     * @param chars 要创建字符串的范围
     * @return 一个随机字符串
     * @throws IllegalArgumentException 如果 {@code count} &lt; 0 或者字符串是空
     */
    public static String random(final int count, final String chars) {
        return RandomStringUtils.random(count, chars);
    }

    /**
     * <p>通过构造函数创建一个新的对象</p>
     * @param <T> 要构造对象的类型
     * @param cls 对象的class, 不能为 {@code null}
     * @param args 构造函数的参数数组
     * @return 返回一个新的实例 {@code cls}, 不为 {@code null}
     * @throws NullPointerException 如果 {@code cls} 是 {@code null}
     * @throws NoSuchMethodException 如果没有对应的构造函数
     * @throws IllegalAccessException if invocation is not permitted by security
     * @throws InvocationTargetException if an error occurs on invocation
     * @throws InstantiationException if an error occurs on instantiation
     * @see #invokeConstructor(java.lang.Class, java.lang.Object[], java.lang.Class[])
     */
    public static <T> T invokeConstructor(final Class<T> cls, Object... args)
        throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        return ConstructorUtils.invokeConstructor(cls, args);
    }

    /**
     * 获取类中所以属性，包括父类的
     * @param cls 要查询的对象的clsss
     * @return 返回所有属性数组 (可能为空).
     * @throws IllegalArgumentException 如果这个class 是 {@code null}
     * @since 3.2
     */
    public static Field[] getAllFields(Class<?> cls) {
        return FieldUtils.getAllFields(cls);
    }

    /**
     * 获取类中所以属性，包括父类的
     * @param cls 要查询的对象的clsss
     * @return 属性的列表集合 (可能为空).
     * @throws IllegalArgumentException 如果这个class是 {@code null}
     * @since 3.2
     */
    public static List<Field> getAllFieldsList(Class<?> cls) {
        return FieldUtils.getAllFieldsList(cls);
    }

    /**
     * 通过属性名获取具体的属性对象
     * @param cls {@link Class} 要获取的类, 不能为空 {@code null}
     * @param fieldName 属性名字
     * @return the 属性对象
     * @throws IllegalArgumentException 如果 class 为{@code null}, 或者这个字段不存在
     */
    public static Field getDeclaredField(final Class<?> cls, final String fieldName) {
        return FieldUtils.getDeclaredField(cls, fieldName);
    }

    /**
     * 通过属性名获取具体的属性对象
     * @param cls {@link Class} 要获取的类, 不能为空 {@code null}
     * @param fieldName 属性名字
     * @param forceAccess 是否能读取
     * @return 属性对象
     * @throws IllegalArgumentException 如果这个class为 {@code null}, 或者这个字段不存在
     */
    public static Field getDeclaredField(final Class<?> cls, final String fieldName, final boolean forceAccess) {
        return FieldUtils.getDeclaredField(cls, fieldName, forceAccess);
    }

    /**
     * 通过名字获取属性
     * @param cls 反射的class， 不能为空{@code null}
     * @param fieldName 属性名
     * @return the 属性对象
     * @throws IllegalArgumentException 如果这个class为 {@code null}, 或者没有这个属性
     */
    public static Field getField(final Class<?> cls, final String fieldName) {

        return FieldUtils.getField(cls, fieldName);
    }

    /**
     * 通过名字获取属性
     * @param cls 要反射的类, 不能为{@code null}
     * @param fieldName 属性名
     * @param forceAccess 是否可以读写
     * @return 属性对象
     * @throws IllegalArgumentException 如果这个class 是 {@code null}，或者没有该属性
     */
    public static Field getField(final Class<?> cls, final String fieldName, final boolean forceAccess) {
        return FieldUtils.getField(cls, fieldName, forceAccess);
    }

    /**
     * 通过属性名读取某个属性,只能测试public
     * @param target 要反射的对象, 不能为{@code null}
     * @param fieldName 属性的名字
     * @return 要设置的值
     * @throws IllegalArgumentException 如果 {@code target} 是 {@code null}, 或者这个属性不存在
     * @throws IllegalAccessException 这个属性名不存在 {@code public}
     */
    public static Object readDeclaredField(final Object target, final String fieldName)
        throws IllegalAccessException {
        return FieldUtils.readDeclaredField(target, fieldName);
    }

    /**
     * 通过属性名字获取某个对象的属性
     * @param target 要反射的对象
     * @param fieldName 属性名字
     * @param forceAccess 是否可以读取
     * @return 返回属性对象
     * @throws IllegalArgumentException 如果 {@code target} 是 {@code null}, 或者没有这个属性
     * @throws IllegalAccessException 如果这个属性不可读取
     */
    public static Object readDeclaredField(final Object target, final String fieldName, final boolean forceAccess)
        throws IllegalAccessException {
        return FieldUtils.readDeclaredField(target, fieldName, forceAccess);
    }

    /**
     * 通过名字调用一个对象的方法
     * @param object 要调用方法的对象那个
     * @param methodName 要调用方法的名字
     * @param args 方法的参数数组
     * @return 方法的返回对象
     * @throws NoSuchMethodException 如果不能发现可读取的方法
     * @throws InvocationTargetException wraps an exception thrown by the method invoked
     * @throws IllegalAccessException if the requested method is not accessible via reflection
     */
    public static Object invokeMethod(final Object object, final String methodName, Object... args)
        throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        return MethodUtils.invokeMethod(object, methodName, args);
    }

    /**
     * <p>通过方法名和参数类型调用一个对象的方法</p>
     * @param object 要调用方法的对象
     * @param methodName 要调用的方法的名字
     * @param args 调用方法的参数数组
     * @param parameterTypes 参数的类型
     * @return 调用方法的返回值
     * @throws NoSuchMethodException if there is no such accessible method
     * @throws InvocationTargetException wraps an exception thrown by the method invoked
     * @throws IllegalAccessException if the requested method is not accessible via reflection
     */
    public static Object invokeMethod(final Object object, final String methodName, Object[] args, Class<?>[] parameterTypes)
        throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        return MethodUtils.invokeMethod(object, methodName, args, parameterTypes);
    }

    /**
     * 复制一个完整的路径到一个新的位置
     * @param srcDir 一个存在的要复制的目录, 不能为 {@code null}
     * @param destDir 一个新的目录, 不能为空 {@code null}
     * @throws NullPointerException if source or destination is {@code null}
     * @throws IOException if source or destination is invalid
     * @throws IOException if an IO error occurs during copying
     * @since 1.1
     */
    public static void copyDirectory(File srcDir, File destDir)
        throws IOException {
        FileUtils.copyDirectory(srcDir, destDir);
    }

    /**
     * 判断文件或目录是否存在
     * @param dirName 文件名
     * @return 存在true，不存在false
     * @version CETCMS 2011-6-13
     */
    public static Boolean isDir(String dirName) {
        File file = new File(dirName);
        if (file.exists()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 复制一个文件到新的位置
     * @param srcFile 要复制的文件, 不能为 {@code null}
     * @param destFile 新文件，不能为 {@code null}
     * @throws NullPointerException 如果源文件或者目标文件为 {@code null}
     * @throws IOException if source or destination is invalid
     * @throws IOException if an IO error occurs during copying
     * @see #copyFileToDirectory(File, File)
     */
    public static void copyFile(File srcFile, File destFile)
        throws IOException {
        FileUtils.copyFile(srcFile, destFile);
    }

    /**
     * 清空一个目录，但是不删除这个目录
     * @param 要清空的目录
     * @throws IOException in case cleaning is unsuccessful
     */
    public static void cleanDirectory(File directory)
        throws IOException {
        FileUtils.cleanDirectory(directory);
    }

    /**
     * 复制一个文件到输出流中
     * @param input 要读取的文件
     * @param output 要写入的输出流
     * @return 文件的字节数
     * @throws NullPointerException if the input or output is null
     * @throws IOException if an I/O error occurs
     * @since 2.1
     */
    public static long copyFile(File input, OutputStream output)
        throws IOException {
        return FileUtils.copyFile(input, output);
    }

    /**
     * 将一个输入流中的数据拷贝到文件中
     * @param source 要拷贝的输入流, 不能为空 {@code null}
     * @param destination 一个文件对象，但是不是一个目录，不能为空
     * @throws IOException if <code>destination</code> is a directory
     * @throws IOException if <code>destination</code> cannot be written
     * @throws IOException if <code>destination</code> needs creating but can't be
     * @throws IOException if an IO error occurs during copying
     * @since 2.0
     */
    public static void copyInputStreamToFile(InputStream source, File destination)
        throws IOException {
        FileUtils.copyInputStreamToFile(source, destination);
    }

    /**
     * 删除一个目录
     * @param directory 要删除的目录
     * @throws IOException 如果删除不成功
     */
    public static void deleteDirectory(File directory)
        throws IOException {
        FileUtils.deleteDirectory(directory);
    }

    /**
     * 创建一个目录，包含子目录
     * @param directory 要创建的目录, 不能为空 {@code null}
     * @throws NullPointerException 如果目录是 {@code null}
     * @throws IOException 如果这个目录不能被创建
     */
    public static void forceMkdir(File directory)
        throws IOException {
        FileUtils.forceMkdir(directory);
    }

    /**
     * 删除一个文件，如果这个文件是个目录，则删除它下面的所以子文件
     * @param file 要删除的文件或者目录, 不能为 {@code null}
     * @throws NullPointerException 如果这个目录是 {@code null}
     * @throws FileNotFoundException 如果这个目录不能发现
     * @throws IOException 删除失败
     */
    public static void forceDelete(File file)
        throws IOException {
        FileUtils.forceDelete(file);
    }

    /**
     * 移动一个目录
     * @param srcDir 被移动的目录
     * @param destDir 目标目录
     * @throws NullPointerException 如果源目录或者目标目录为 {@code null}
     * @throws FileExistsException 如果这个目标目录存在
     * @throws IOException 如果源目录或目标目录非法
     * @throws IOException if an IO error occurs moving the file
     * @since 1.4
     */
    public static void moveDirectory(File srcDir, File destDir)
        throws IOException {
        FileUtils.moveDirectory(srcDir, destDir);
    }

    /**
     * 覆盖方式写
     * @param fileName 文件名
     * @param context 内容
     * @date 2011-5-23
     */
    public static void writeFileForOver(String fileName, String context) {
        OutputStream os;
        try {
            os = new FileOutputStream(fileName);
            // 套上字符缓冲流
            BufferedOutputStream bout = new BufferedOutputStream(os);

            byte[] buff = context.getBytes();

            bout.write(buff);
            bout.flush();
            bout.close();

        } catch (FileNotFoundException e) {
            LOGGER.error("[文件操作]  文件没找到:文件名" + fileName + e.getMessage());
        } catch (IOException e) {
            LOGGER.error("[文件操作]  文件覆盖写入出错:文件名" + fileName + e.getMessage());
        }
    }

    /**
     * 追加方式写
     * @param fileName 文件名
     * @param context 内容
     * @date 2011-5-23
     */
    public static void writerFileForAppend(String fileName, String context) {
        OutputStream os;
        try {
            os = new FileOutputStream(fileName, true);
            // 创建字符缓冲流
            BufferedOutputStream bout = new BufferedOutputStream(os);

            byte[] buff = context.getBytes();

            bout.write(buff);
            bout.flush();
            bout.close();

        } catch (FileNotFoundException e) {
            LOGGER.error("[文件操作]  文件没找到:文件名" + fileName + e.getMessage());
        } catch (IOException e) {
            LOGGER.error("[文件操作]  文件追加写入出错:文件名" + fileName + e.getMessage());
        }
    }

    /**
     * 读取文件内容
     * @param fileName 文件名
     * @return String 文件内容
     * @throws IOException
     * @date 2011-5-23
     */
    public static String readFile(String fileName)
        throws IOException {
        StringBuilder stb = new StringBuilder();
        InputStream is = new FileInputStream(fileName);
        // 定义一个字节类型数组，所有的文件都是字节形式存在的
        byte[] buff = new byte[200];// 每次从文件中读取200个字节
        // 每次读取的实际字节长度
        int length = 0;

        // is.read()方法：从buff缓中区的第0个位开始读取字节，每次最多读取200，
        // 方法会返回一个实际读取的长度，用length接收，当值为-1时，表示所有的字节全部读取完毕
        while ((length = is.read(buff, 0, 200)) != -1) {
            // 把字节以平台的默认编码方式转为字符，从buff的第0个位开始转换，实际要转换的长度是length
            stb.append(new String(buff, 0, length));
        }
        // 关闭流
        is.close();
        return stb.toString();

    }

    /**
     * 获取当前目录下所有的文件名
     * @param dirName 路径名
     * @param postfix 文件后缀名
     * @return 目录下所有文件名String[]
     * @date 2011-5-24
     */
    public static String[] getCurrFile(String dirName, String postfix) {

        File dirFile = new File(dirName);
        String[] fileNames = dirFile.list();
        List<String> list = new ArrayList<String>();
        // 文件过滤，只需要txt文件,防止非指令文件读取
        for (String name : fileNames) {
            // 文件名过滤
            if (name.endsWith(postfix)) {
                // System.out.println(name); // 只打印该目录下的.xml文件
                list.add(dirName + "/" + name);
            }
        }

        if (fileNames.length == 0) return null;
        // 把泛型转成字符数组
        String[] result = new String[list.size()];
        for (int i = 0; i < list.size(); i++ ) {
            result[i] = list.get(i);
        }
        return result;
    }

    /**
     * 删除文件--删除单个文件
     * @param fileName 文件名
     * @date 2011-6-13
     */
    public static void delFile(String fileName) {
        File delFile = new File(fileName);
        delFile.delete();
    }

    /**
     * 得到发布根目录
     * @return hong Company huilet 2013-1-11
     */
    public static String getRootPath() {

        // file:/D:/ResumeParser/WebRoot/WEB-INF/classes/util/Application.class

        String result = CommUtils.class.getResource("CommUtils.class").toString();

        int index = result.indexOf("WEB-INF");

        if (index == -1) {
            index = result.indexOf("bin");

        }
        result = result.substring(0, index);
        if (result.startsWith("jar")) {

            // 当class文件在jar文件中时，返回"jar:file:/F:/ ..."样的路径

            result = result.substring(10);

        } else if (result.startsWith("file")) {

            // 当class文件在class文件中时，返回"file:/F:/ ..."样的路径

            result = result.substring(6);

        }

        if (result.endsWith("/")) {

            result = result.substring(0, result.length() - 1);// 不包含最后的"/"
        }
        Properties props = System.getProperties(); // 获得系统属性集
        String osName = props.getProperty("os.name"); // 操作系统名称
        // System.out.println("os------>"+osName);
        if ("Linux".equals(osName)) {
            result = "/" + result;
        }
        return result;
    }

    /**
     * 通过文件路径得到文件
     * @param url
     * @return
     */
    public static File getFileByUrl(String url) {
        return new File(url);
    }

    /**
     * 得到文件大小
     * @param url
     * @return
     */
    public static long getFileSizes(String url) {
        long s = -1;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(getFileByUrl(url));
            s = fis.available();
        } catch (FileNotFoundException e) {
            LOGGER.info("程序没有找到这个文件... ... ");
        } catch (IOException e) {
            LOGGER.info("程序没有找到这个文件... ... ");
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    LOGGER.error(e.toString());
                }
            }
        }
        return s;
    }

    /**
     * 将json转换成map
     * 
     * <pre>
     * 格式  [
     *         [key,value],
     *         [key,value]
     *     ]
     * </pre>
     * 
     * @param jsonStr
     * @return
     */
    public static Map<Integer, Integer> json2Map(String jsonStr) {
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        JSONArray parentArray = JSONArray.parseArray(jsonStr);
        List<Integer> list = null;
        for (int i = 0; i < parentArray.size(); i++ ) {
            list = JSONArray.parseArray(parentArray.getString(i), Integer.class);
            map.put(list.get(0), list.get(1));
        }
        return map;
    }

    /**
     * 匹配正则表达式
     * @param regex regex
     * @param value value
     * @return boolean
     */
    public static boolean match(String regex, String value) {
        Pattern pattern = Pattern.compile(regex);

        if (pattern.matcher(value).find()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 区分大小写
     * @param regex regex
     * @param flags flags
     * @param value value
     * @return boolean
     */
    public static boolean match(String regex, int flags, String value) {
        Pattern pattern = Pattern.compile(regex, flags);

        if (pattern.matcher(value).find()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 邮箱验证工具
     * @param value value
     * @return boolean
     */
    public static boolean isEmail(String value) {
        String check = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";

        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 手机号码验证
     * @param value value
     * @return boolean
     */
    public static boolean isMobile(String value) {
        String check = "^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\\d{8})$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 座机验证
     * @param value value
     * @return boolean
     */
    public static boolean isTel(String value) {
        String check = "^\\d{3,4}-?\\d{7,9}$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 电话号码 包括移动电话和座机
     * @param value value
     * @return boolean
     */
    public static boolean isPhone(String value) {
        String telcheck = "^\\d{3,4}-?\\d{7,9}$";
        String mobilecheck = "^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\\d{8})$";

        if (match(telcheck, Pattern.CASE_INSENSITIVE, value) || match(mobilecheck, Pattern.CASE_INSENSITIVE, value)) {
            return true;
        } else
            return false;
    }

    /**
     * @param value 输入内容限制为英文字母 、数字和下划线
     * @return boolean
     */
    public static boolean isGeneral(String value) {
        String check = "^\\w+$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    public static boolean isGeneral(String value, int min, int max) {
        String check = "^\\w{" + min + "," + max + "}$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 判断是否是生日
     * @param value value
     * @return boolean
     */
    public static boolean isBirthDay(String value) {
        String check = "(\\d{4})(/|-|\\.)(\\d{1,2})(/|-|\\.)(\\d{1,2})$";

        if (match(check, Pattern.CASE_INSENSITIVE, value)) {
            int year = Integer.parseInt(value.substring(0, 4));
            int month = Integer.parseInt(value.substring(5, 7));
            int day = Integer.parseInt(value.substring(8, 10));

            if (month < 1 || month > 12) return false;

            if (day < 1 || day > 31) return false;

            if ((month == 4 || month == 6 || month == 9 || month == 11) && day == 31) return false;

            if (month == 2) {
                boolean isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
                if (day > 29 || (day == 29 && !isleap)) return false;
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * 身份证
     * @param value value
     * @return boolean
     */
    public static boolean isIdentityCard(String value) {
        String check = "(^\\d{15}$)|(^\\d{17}([0-9]|X)$)";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 邮政编码
     * @param value value
     * @return boolean
     */
    public static boolean isZipCode(String value) {
        String check = "^[0-9]{6}$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 货币
     * @param value value
     * @return boolean
     */
    public static boolean isMoney(String value) {
        String check = "^(\\d+(?:\\.\\d{1,2})?)$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 大于0的数字
     * @param value value
     * @return boolean
     */
    public static boolean isNumber(String value) {
        String check = "^(\\+|\\-)?\\d+$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    public boolean isNumber(String value, int min, int max) {
        String check = "^(\\+|\\-)?\\d{" + min + "," + max + "}$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 正整数
     * @param value value
     * @return boolean
     */
    public static boolean isPositiveNumber(String value) {
        String check = "^\\d+$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 正整数
     * @param value
     * @param min范围
     * @param max
     * @return
     */
    public static boolean isPositiveNumber(String value, int min, int max) {
        String check = "^\\d{" + min + "," + max + "}$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 中文
     * @param value value
     * @return boolean
     */
    public static boolean isChinese(String value) {
        String check = "^[\\u2E80-\\u9FFF]+$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 是中文
     * @param value
     * @param min
     * @param max
     * @return
     */
    public static boolean isChinese(String value, int min, int max) {
        String check = "^[\\u2E80-\\u9FFF]{" + min + "," + max + "}$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 中文字、英文字母、数字和下划线
     * @param value value
     * @return boolean
     */
    public static boolean isString(String value) {
        String check = "^[\\u0391-\\uFFE5\\w]+$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 中文字、英文字母、数字和下划线
     * @param value value
     * @return boolean
     */
    public static boolean isString(String value, int min, int max) {
        String check = "^[\\u0391-\\uFFE5\\w]{" + min + "," + max + "}$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * UUID
     * @param value value
     * @return boolean
     */
    public static boolean isUUID(String value) {
        String check = "^[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 礼品卡前缀
     * @param value value
     * @return boolean
     */
    public static boolean isCardPrefix(String value) {
        String check = "^[A-Za-z]\\w{0,3}\\d{0,4}$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 礼品卡格式
     * @param value value
     * @return boolean
     */
    public static boolean isCard(String value) {
        String check = "^[A-Za-z]\\w{3}\\d{4}$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 匹配是否是链接
     * @param value value
     * @return boolean
     */
    public static boolean isUrl(String value) {
        String check = "^((https?|ftp):\\/\\/)?(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$";
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 判断
     * @param value value
     * @return boolean
     */
    public static boolean isDateTime(String value) {
        String check = "^(\\d{4})(/|-|\\.|年)(\\d{1,2})(/|-|\\.|月)(\\d{1,2})(日)?(\\s+\\d{1,2}(:|时)\\d{1,2}(:|分)?(\\d{1,2}(秒)?)?)?$";// check =
        return match(check, Pattern.CASE_INSENSITIVE, value);
    }

    /**
     * 字符在指定范围
     * @param value
     * @param min
     * @param max
     * @return
     */
    public static boolean isLength(String value, int min, int max) {
        int length = isEmpty(value) ? 0 : value.length();
        if (length >= min && length <= max)
            return true;
        else
            return false;
    }

    /**
     * 比较两个日期
     * @param date1
     * @param date2
     * @return
     */
    public static boolean compareDate(String date1, String date2) {
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATETIME);
        try {
            Date d1 = sdf.parse(date1);
            Date d2 = sdf.parse(date2);
            return d1.compareTo(d2) > 0;
        } catch (ParseException e) {
            return false;
        }

    }

    /**
     * sleep等待,单位为毫秒,忽略InterruptedException.
     */
    public static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    /**
     * sleep等待,忽略InterruptedException.
     */
    public static void sleep(long duration, TimeUnit unit) {
        try {
            Thread.sleep(unit.toMillis(duration));
        } catch (InterruptedException e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    /**
     * 按照ExecutorService JavaDoc示例代码编写的Graceful Shutdown方法. 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务. 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
     * 如果仍然超时，则强制退出. 另对在shutdown时线程本身被调用中断做了处理.
     */
    public static void gracefulShutdown(ExecutorService pool, int shutdownTimeout, int shutdownNowTimeout, TimeUnit timeUnit) {
        pool.shutdown(); // Disable new tasks from being submitted
        try {
            // Wait a while for existing tasks to terminate
            if (!pool.awaitTermination(shutdownTimeout, timeUnit)) {
                pool.shutdownNow(); // Cancel currently executing tasks
                // Wait a while for tasks to respond to being cancelled
                if (!pool.awaitTermination(shutdownNowTimeout, timeUnit)) {
                    System.err.println("Pool did not terminated");
                }
            }
        } catch (InterruptedException ie) {
            // (Re-)Cancel if current thread also interrupted
            pool.shutdownNow();
            // Preserve interrupt status
            Thread.currentThread().interrupt();
        }
    }

    /**
     * 直接调用shutdownNow的方法, 有timeout控制.取消在workQueue中Pending的任务,并中断所有阻塞函数.
     */
    public static void normalShutdown(ExecutorService pool, int timeout, TimeUnit timeUnit) {
        try {
            pool.shutdownNow();
            if (!pool.awaitTermination(timeout, timeUnit)) {
                System.err.println("Pool did not terminated");
            }
        } catch (InterruptedException ie) {
            Thread.currentThread().interrupt();
        }
    }

    /**
     * 将json格式的字符串解析成Map对象 <li> json格式：{"name":"admin","retries":"3fff","testname" :"ddd","testretries":"fffffffff"}
     */
    public static HashMap<String, Object> toHashMap(Object object) {
        HashMap<String, Object> data = new HashMap<String, Object>();
        // 将json字符串转换成jsonObject
        JSONObject jsonObject = JSONObject.parseObject((String) object);
        // 遍历jsonObject数据，添加到Map对象
        for (String key : jsonObject.keySet()) {
            String value = jsonObject.getString(key);
            data.put(key, value);
        }
        return data;
    }

    /** 去掉theString中的一些转义字符,如\ \n \r \t. */
    public static String string2JsonString(String theString) {
        if (StringUtils.isNotEmpty(theString)) {
            theString = theString.replace("\\", "\\\\");// 对斜线的转义
            theString = theString.replace("\n", "\\n"); // \\f \\b '/': -- > \\/
            theString = theString.replace("\r", "\\r");
            theString = theString.replace("\t", "\\t");
        }
        return theString;
    }

    /**
     * json转换list. <br>详细说明
     * @param jsonStr json字符串
     * @return
     * @return List<Map<String,Object>> list
     */
    public static List<Map<String, Object>> parseJSON2List(String jsonStr) {
        jsonStr = string2JsonString(jsonStr);
        JSONArray jsonArr = JSONArray.parseArray(jsonStr);
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Iterator<Object> it = jsonArr.iterator();
        while (it.hasNext()) {
            list.add(parseJSON2Map(JSONObject.toJSONString(it.next())));
        }
        return list;
    }

    /**
     * json转换map. <br>详细说明 @param jsonStr json字符串 @return @return Map<String,Object> 集合 @throws
     */
    public static Map<String, Object> parseJSON2Map(String jsonStr) {
        ListOrderedMap map = new ListOrderedMap();
        // 最外层解析
        JSONObject json = JSONObject.parseObject(jsonStr);
        for (Object k : json.keySet()) {
            Object v = json.get(k);
            // 如果内层还是数组的话，继续解析
            if (v instanceof JSONArray) {
                List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
                Iterator<Object> it = ((JSONArray) v).iterator();
                while (it.hasNext()) {
                    list.add(parseJSON2Map(JSONObject.toJSONString(it.next())));
                }
                map.put(k.toString(), list);
            } else {
                map.put(k.toString(), v);
            }
        }
        return map;
    }

    /**
     * 通过HTTP获取JSON数据. <br>通过HTTP获取JSON数据返回list @param url 链接 @return @return List<Map<String,Object>> list @throws
     */
    public static List<Map<String, Object>> getListByUrl(String url) {
        try {
            // 通过HTTP获取JSON数据
            InputStream in = new URL(url).openStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            return parseJSON2List(sb.toString());
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
        }
        return null;
    }

    /**
     * 通过HTTP获取JSON数据. <br>通过HTTP获取JSON数据返回map @param url 链接 @return @return Map<String,Object> 集合 @throws
     */
    public static Map<String, Object> getMapByUrl(String url) {
        try {
            // 通过HTTP获取JSON数据
            InputStream in = new URL(url).openStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            return parseJSON2Map(sb.toString());
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
        }
        return null;
    }

    /**
     * map转换json. <br>详细说明 @param map 集合 @return @return String json字符串 @throws
     */
    public static String mapToJson(Map<String, String> map) {
        Set<String> keys = map.keySet();
        String key = "";
        String value = "";
        StringBuffer jsonBuffer = new StringBuffer();
        jsonBuffer.append("{");
        for (Iterator<String> it = keys.iterator(); it.hasNext();) {
            key = (String) it.next();
            value = map.get(key);
            jsonBuffer.append(key + ":" + "\"" + value + "\"");
            if (it.hasNext()) {
                jsonBuffer.append(",");
            }
        }
        jsonBuffer.append("}");
        return jsonBuffer.toString();
    }

    /**
     * json字符串转换为list
     * @param jsonString
     * @param pojoClass
     * @return
     */
    public static List getList4Json(String jsonString, Class pojoClass) {
        JSONArray jsonArray = JSONArray.parseArray(jsonString);
        JSONObject jsonObject;
        Object pojoValue;
        List list = new ArrayList();
        for (int i = 0; i < jsonArray.size(); i++ ) {
            jsonObject = jsonArray.getJSONObject(i);
            pojoValue = JSONObject.toJavaObject(jsonObject, pojoClass);
            list.add(pojoValue);
        }
        return list;
    }

    /**
     * 将list数组转换成json
     * @param list
     * @return
     */
    public static JSONArray getJsonArrayByList(List list) {
        return JSONArray.parseArray(JSONObject.toJSONString(list));
    }

    /**
     * 将一个对象转换成json字符串
     * @param object
     * @return
     */
    public static String objectToJson(Object object) {
        StringBuilder json = new StringBuilder();
        if (object == null) {
            json.append("\"\"");
        } else if (object instanceof String || object instanceof Integer || object instanceof Date || object instanceof Double || object instanceof Boolean) {
            json.append("\"").append(object.toString()).append("\"");
        } else {
            json.append(beanToJson(object));
        }
        return json.toString();
    }

    /**
     * 将一个bean转换成json
     * @param bean
     * @return
     */
    public static String beanToJson(Object bean) {
        StringBuilder json = new StringBuilder();
        json.append("{");
        PropertyDescriptor[] props = null;
        try {
            props = Introspector.getBeanInfo(bean.getClass(), Object.class).getPropertyDescriptors();
        } catch (IntrospectionException e) {}
        if (props != null) {
            for (int i = 0; i < props.length; i++ ) {
                try {
                    String name = objectToJson(props[i].getName());
                    String value = objectToJson(props[i].getReadMethod().invoke(bean));
                    if (name.equals("\"callbacks\"")) value = "\"\"";
                    json.append(name);
                    json.append(":");
                    json.append(value);
                    json.append(",");
                } catch (Exception e) {
                    LOGGER.error(e.getMessage());
                }
            }
            json.setCharAt(json.length() - 1, '}');
        } else {
            json.append("}");
        }
        return json.toString();
    }

    /**
     * 把list转换成json
     * @param list
     * @return
     */
    public static String listToJson(List<?> list) {
        StringBuilder json = new StringBuilder();
        json.append("[");
        if (list != null && list.size() > 0) {
            for (Object obj : list) {
                json.append(objectToJson(obj));
                json.append(",");
            }
            json.setCharAt(json.length() - 1, ']');
        } else {
            json.append("]");
        }
        return json.toString();
    }

    /**
     * 格式 [ ["货币资金","1","74893.00"], ["短期投资","2",""] ]
     * @param jsonStr
     * @return
     */
    public static Map<Integer, List<String>> jsonArray2Map(String jsonStr) {
        Map<Integer, List<String>> map = new HashMap<Integer, List<String>>();
        JSONArray parentArray = JSONArray.parseArray(jsonStr);
        List<String> list = null;
        for (int i = 0; i < parentArray.size(); i++ ) {
            list = JSONArray.parseArray(parentArray.getString(i), String.class);
            map.put(i, list);
        }
        return map;
    }

    /**
     * List<Map<String,Object>> 转成json.
     * @return 返回数组类，如果没有书籍就返回[] [{"id":"id","orderNum":1},{"id":"id","orderNum":1}]
     */
    public static String getJsonListMap(List<Map<String, Object>> listMap) {
        if (listMap != null) {
            JSONArray jsonArray = new JSONArray();
            for (Map<String, Object> map : listMap) {
                JSONObject jsonObject = new JSONObject(map);
                jsonArray.add(jsonObject);
            }
            return jsonArray.toJSONString();
        }
        return "[]";
    }

    /**
     * 把时间控件的时间转换为十四位的时间 (如:2008-12-24 14:37:19转为20081224143719)
     * @param strDate 字符串
     * @return String
     */
    public static String dateToStringDate(String strDate) {
        if (null == strDate || "".equals(strDate)) {
            return "";
        }

        // 正则表达式
        String regex = "[-:\\s]";

        // 替换(:- )
        String str = strDate.replaceAll(regex, "");

        return str;
    }

    /**
     * 生成给定时间字符串，一时间字符串格式为"YYYY年MM月DD日HH时MM分SS秒"
     * @return 当前时间字符串
     */
    public static String generateTime() {
        Date date = new Date();
        StringBuffer rtndate = new StringBuffer();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);

        rtndate.append(getYear(calendar) + "年");
        rtndate.append(getMonth(calendar) + "月");
        rtndate.append(getDay(calendar) + "日");
        rtndate.append(getHours(calendar) + "时");
        rtndate.append(getMinutes(calendar) + "分");
        rtndate.append(getSeconds(calendar) + "秒");
        return rtndate.toString();
    }

    /**
     * 生成给定时间字符串，一时间字符串格式为"YYYY年MM月DD日HH时MM分SS秒"
     * @return 当前时间字符串
     */
    public static String generateDayTime() {
        Date date = new Date();
        StringBuffer rtndate = new StringBuffer();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);

        rtndate.append(getYear(calendar) + "年");
        rtndate.append(getMonth(calendar) + "月");
        rtndate.append(Integer.valueOf(getDay(calendar)) + "日");
        return rtndate.toString();
    }

    /**
     * 生成给定时间字符串，一时间字符串格式为"YYYY年MM月DD日HH时MM分SS秒"
     * @return 当前时间字符串
     */
    public static String getDate() {
        Date date = new Date();
        StringBuffer rtndate = new StringBuffer();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);

        rtndate.append(getYear(calendar));
        rtndate.append(getMonth(calendar));
        rtndate.append(getDay(calendar));

        return rtndate.toString();
    }

    /**
     * 生成给定时间字符串，一时间字符串格式为"YYYY年MM月DD日HH时MM分SS秒"
     * @return 当前时间字符串
     */
    public static String getCurrentlyDate() {
        Date date = new Date();
        StringBuffer rtndate = new StringBuffer();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);

        rtndate.append(getYear(calendar));
        rtndate.append("-" + getMonth(calendar));
        rtndate.append("-" + getDay(calendar));

        return rtndate.toString();
    }

    /**
     * 获得给定时间的年信息
     * @param c 时间
     * @return 四位的年信息，如：2005
     */
    public static String getYear(Calendar c) {
        return String.valueOf(c.get(Calendar.YEAR));
    }

    /**
     * 获得给定时间的月信息
     * @param c 时间
     * @return 2位的月信息，如：06
     */
    public static String getMonth(Calendar c) {
        int month = c.get(Calendar.MONTH) + 1;
        if (month < 10) {
            return "0" + String.valueOf(month);
        } else {
            return String.valueOf(month);
        }
    }

    /**
     * 获得给定时间的日信息
     * @param c 时间
     * @return 2位的日信息，如：01
     */
    public static String getDay(Calendar c) {
        int day = c.get(Calendar.DAY_OF_MONTH);
        if (day < 10) {
            return "0" + String.valueOf(day);
        } else {
            return String.valueOf(day);
        }

    }

    /**
     * 获得给定时间的年信息
     * @return 四位的年信息，如：2005
     */
    public static String getYear() {
        Date date = new Date();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        return String.valueOf(calendar.get(Calendar.YEAR));
    }

    /**
     * 获得给定前几年的时间的年信息
     * @param n 减少的年份.
     * @return 四位的年信息，如：2005
     */
    public static String getBeforeYear(int n) {
        Date date = new Date();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        return String.valueOf(calendar.get(Calendar.YEAR) - n);
    }

    /**
     * 获得给定时间的月信息
     * @return 2位的月信息，如：06
     */
    public static String getMonth() {
        Date date = new Date();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        int month = calendar.get(Calendar.MONTH) + 1;
        return String.valueOf(month);
    }

    /**
     * 获取给定日期下一个月
     */
    public static Date getLastMonth(Date s) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(s);
        cal.add(Calendar.MONTH, +1);
        return cal.getTime();
    }

    /**
     * 获得上个月时间的月信息
     * @return 2位的月信息，如：06
     */
    public static String getLastMonth() {
        SimpleDateFormat sdf = new SimpleDateFormat("M");
        Date date = new Date();

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, -1);

        return sdf.format(cal.getTime());
    }

    /**
     * 获得上个月时间的年月信息
     * @return 6位的月信息，如：201406
     */
    public static String getLastYearMonth() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        Date date = new Date();

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, -1);

        return sdf.format(cal.getTime());
    }

    /**
     * 获得指定上几个月或下几个月的年月信息
     * @param month 负数上几个月，正数下几个月。如：-2代表上上个月
     * @return 6位的月信息，如：201406
     */
    public static String getLastYearMonth(int month) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        Date date = new Date();

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, month);

        return sdf.format(cal.getTime());
    }

    /**
     * 获得给定时间的日信息
     * @return 2位的日信息，如：01
     */
    public static String getDay() {
        Date date = new Date();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        return String.valueOf(day);
    }

    /**
     * 获得给定时间的小时信息
     * @param c 时间
     * @return 2位的小时信息，24H，如：13
     */
    public static String getHours(Calendar c) {
        int hours = c.get(Calendar.HOUR_OF_DAY);
        if (hours < 10) {
            return "0" + String.valueOf(hours);
        } else {
            return String.valueOf(hours);
        }
    }

    /**
     * 获得给定时间的分钟信息
     * @param c 时间
     * @return 2位的分钟信息，如：07
     */
    public static String getMinutes(Calendar c) {
        int minutes = c.get(Calendar.MINUTE);
        if (minutes < 10) {
            return "0" + String.valueOf(minutes);
        } else {
            return String.valueOf(minutes);
        }
    }

    /**
     * 获得给定时间的秒信息
     * @param c 时间
     * @return 2位的秒信息，如：03
     */
    public static String getSeconds(Calendar c) {
        int seconds = c.get(Calendar.SECOND);

        if (seconds < 10) {
            return "0" + String.valueOf(seconds);
        } else {
            return String.valueOf(seconds);
        }
    }

    /**
     * 获得给定时间的毫秒信息
     * @param c 时间
     * @return 2位的秒信息，如：03
     */
    public static String getMilliSeconds(Calendar c) {

        int milliSeconds = c.get(Calendar.MILLISECOND);

        if (milliSeconds < 10) {
            return "0" + String.valueOf(milliSeconds);
        } else {
            return String.valueOf(milliSeconds);
        }
    }

    /**
     * 获取当前日期时间
     * @return GregorianCalendar
     */
    public static GregorianCalendar getCurrDateTime() {
        Date date = new Date();
        GregorianCalendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        return calendar;
    }

    /**
     * 将字符串转换成日期 yyyy-MM-dd HH:mm:ss
     */
    public static Date stringToTime(String datetime) {
        if (null != datetime) {
            SimpleDateFormat format = new SimpleDateFormat(FORMAT_DATETIME);

            try {
                return format.parse(datetime.trim());
            } catch (ParseException e) {
                LOGGER.error("stringToTime转换失败", e.getMessage());
            }
        }

        return null;
    }

    /**
     * 获得年月日时分秒
     * @return 日期 如：2014-10-12 12:23:08
     */
    public static String getDateTime() {
        Calendar date = Calendar.getInstance();

        String year = getYear(date);
        String month = getMonth(date);
        String day = getDay(date);

        String hour = getHours(date);
        String minute = getMinutes(date);
        String second = getSeconds(date);

        String calendar = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;

        return calendar;
    }

    /**
     * 获得诊断开始的年月日时分秒毫秒
     * @return 日期 如：2014-10-12 12:23:08 100
     */
    public static String getDiagnoseTime() {
        Calendar date = Calendar.getInstance();

        String year = getYear(date);
        String month = getMonth(date);
        String day = getDay(date);

        String hour = getHours(date);
        String minute = getMinutes(date);
        String second = getSeconds(date);
        // String milliSecond = getMilliSeconds(date);
        String calendar = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;

        return calendar;
    }

    /**
     * 获得当前时间戳的年月日时分秒毫秒
     * @return 日期 如：20141012122308100
     */
    public static String getCurryDateTime() {
        Calendar date = Calendar.getInstance();

        String year = getYear(date);
        String month = getMonth(date);
        String day = getDay(date);

        String hour = getHours(date);
        String minute = getMinutes(date);
        String second = getSeconds(date);
        String milliSecond = getMilliSeconds(date);

        String calendar = year + month + day + hour + minute + second + milliSecond;

        return calendar;
    }

    /**
     * @return 当前时间
     */
    public static Date getDate(int hours, int minutes, int seconds) {
        Calendar calendar = new GregorianCalendar();
        calendar.set(Calendar.HOUR_OF_DAY, hours);
        calendar.set(Calendar.MINUTE, minutes);
        calendar.set(Calendar.SECOND, seconds);
        return calendar.getTime();
    }

    /**
     * 获得给定时间的秒信息
     * @return 星期 如：1
     */
    public static int getWeekDay() {
        Calendar date = Calendar.getInstance();
        int weekday = date.get(Calendar.DAY_OF_WEEK);

        return weekday;
    }

    /**
     * 给定年月，获取这个月的最大天数
     * @return 如：30
     * @throws ParseException
     */
    public static int getDays(String yearMonth)
        throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");

        Calendar c = Calendar.getInstance();

        Date date = sdf.parse(yearMonth);

        c.setTime(date);

        int days = c.getActualMaximum(Calendar.DAY_OF_MONTH);

        return days;
    }

    /**
     * 判断是否是周末的日期
     * @return
     * @throws ParseException
     */
    public static boolean isWeekDay(String strDate)
        throws ParseException {
        boolean isWeekDay = false;

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

        Date date = sdf.parse(strDate);

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;

        if (dayOfWeek == 0 || dayOfWeek == 6) {
            isWeekDay = true;
        }

        return isWeekDay;
    }

    /**
     * 计算两个日期之间相差的天数
     * @param smdate 较小的时间
     * @param bdate 较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date smdate, Date bdate)
        throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long betweenDays = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(betweenDays));
    }

    /**
     * 字符串的日期格式的计算
     */
    public static int daysBetween(String smdate, String bdate)
        throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(smdate));
        long time1 = cal.getTimeInMillis();
        cal.setTime(sdf.parse(bdate));
        long time2 = cal.getTimeInMillis();
        long betweenDays = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(betweenDays));
    }

    /**
     * 根据日期获得所在周的日期
     * @param mdate
     * @return
     */
    @SuppressWarnings("deprecation")
    public static List<String> dateToWeek(Date mdate) {
        int b = mdate.getDay();
        Date fdate;
        // List<Date> list = new ArrayList<Date>();
        List<String> list = new ArrayList<String>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (b == 0) {
            b = 7;
        }
        Long fTime = mdate.getTime() - b * 24 * 3600000;
        for (int a = 1; a <= 7; a++ ) {
            fdate = new Date();
            fdate.setTime(fTime + (a * 24 * 3600000));
            // list.add(a-1, fdate);
            list.add(sdf.format(fdate).toString());
        }
        return list;
    }

    /**
     * 根据日期获得所在第几周
     * @param mdate
     * @return
     */
    @SuppressWarnings("deprecation")
    public static Integer dateToWeeknum(Date mdate, Date sdate) {
        int b = sdate.getDay();
        Date fdate;

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (b == 0) {
            b = 7;
        }
        Long fTime = sdate.getTime() - b * 24 * 3600000;
        fdate = new Date();
        fdate.setTime(fTime);
        int s = 0;
        try {
            s = daysBetween(fdate, mdate) - 1;
            s = s / 7 + 1;
        } catch (ParseException e) {
            LOGGER.error("dateToWeeknum,获取周失败", e.getMessage());
            e.printStackTrace();
        }
        return s;
    }

    /**
     * 获得指定多少天的日历
     */
    public static Date getLastYearWeek(int day) {
        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH, day);

        return cal.getTime();
    }

    /**
     * 获得指定周次的日期
     * @param
     * @return start 为学期开始时间， weeks为多少周，day为周几
     */
    public static Date getCurrentDateForWeek(Date start, int weeks, int day) {
        int b = start.getDay();
        Date fdate;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Long fTime = start.getTime() - (b - 1) * 24 * 3600000;
        fdate = new Date();
        fdate.setTime(fTime);

        int s = (weeks - 1) * 7 + day - 1;

        Calendar cal = Calendar.getInstance();
        cal.setTime(fdate);
        cal.add(Calendar.DAY_OF_MONTH, s);

        return cal.getTime();
    }

    /**
     * 计算两个日期之间相差的小时
     * @param smdate 较小的时间
     * @param bdate 较大的时间
     * @return 相差小时数
     * @throws ParseException
     */
    public static double hoursBetween(Date smdate, Date bdate)
        throws ParseException {
        double result = dateDiffHour(smdate, bdate);
        return result;
    }

    private static double dateDiffHour(Date startTime, Date endTime)
        throws ParseException {
        // SimpleDateFormat sd = new SimpleDateFormat(FORMAT_DATETIME);
        long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数
        long nh = 1000 * 60 * 60;// 一小时的毫秒数
        long nm = 1000 * 60;// 一分钟的毫秒数
        // 获得两个时间的毫秒时间差异
        long time1 = startTime.getTime();
        long time2 = endTime.getTime();
        long diff;
        if (time1 > time2) {
            diff = time1 - time2;
        } else {
            diff = time2 - time1;
        }
        long day = diff / nd;// 计算差多少天
        long hour = (diff % nd) / nh;// 计算差多少小时
        long min = (diff % nd % nh) / nm;// 计算差多少分钟

        double doubleMin = min;
        // 相差的小时数
        double result = day * 24 + hour + (doubleMin / 60);
        BigDecimal bg = new BigDecimal(result);
        // 四舍五入保留1位小数
        result = bg.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
        return result;
    }

    /**
     * 日期间隔分钟数
     */
    public static int minsBetween(Date smdate, Date bdate) {
        // SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATETIME);
        try {
            Calendar cal = Calendar.getInstance();
            cal.setTime(smdate);
            long time1 = cal.getTimeInMillis();
            cal.setTime(bdate);
            long time2 = cal.getTimeInMillis();
            long betweenDays = (time2 - time1) / (1000 * 60);

            return Integer.parseInt(String.valueOf(betweenDays));
        } catch (Exception e) {
            return 9999;
        }

    }

    /**
     * 检查str是否在list中
     * @param list
     * @param str
     * @return true : 在，false : 不在
     */
    public static boolean strInList(List<String> list, String str) {
        boolean flag = false;

        if (list != null && list.size() > 0 && !isEmpty(str)) {
            for (String curStr : list) {
                if (curStr.equals(str)) {
                    flag = true;
                    break;
                }
            }
        }

        return flag;
    }

    /**
     * 判断是否为空，如果是则返回“”，不是返回该值
     * @param cs
     * @return
     */
    private static String nvl(String cs) {
        return nvl(cs, "");
    }

    /**
     * 判断是否为空，如果是则返回默认值，不是返回该值
     * @param cs
     * @param defaultStr
     * @return
     */
    private static String nvl(String cs, String defaultStr) {
        return cs == null ? defaultStr : cs;
    }

    /**
     * 判断是否为空，如果是则返回默认值，不是返回该对象
     */
    private static <T> T objNVL(Object cs, T defaultV, Class<T> requiredType) {
        return cs == null ? defaultV : (T) cs;
    }

    /**
     * 将byte数组转换成字符串
     * @param value
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String getStrByBytes(byte[] value)
        throws UnsupportedEncodingException {
        return new String(value, "UTF-8");
    }

    /**
     * <p> 首字母大写 </p>
     * 
     * <pre>
     * StringUtils.capitalize(null)  = null
     * StringUtils.capitalize("")    = ""
     * StringUtils.capitalize("cat") = "Cat"
     * StringUtils.capitalize("cAt") = "CAt"
     * </pre>
     */
    public static String capitalize(final String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return str;
        }
        char firstChar = str.charAt(0);
        if (Character.isTitleCase(firstChar)) {
            // already capitalized
            return str;
        }
        return new StringBuilder(strLen).append(Character.toTitleCase(firstChar)).append(str.substring(1)).toString();
    }

    /**
     * <p> 在左边添加指定字符达到指定的长度 </p>
     * 
     * <pre>
     * StringUtils.leftPad(null, *, *)     = null
     * StringUtils.leftPad("", 3, 'z')     = "zzz"
     * StringUtils.leftPad("bat", 3, 'z')  = "bat"
     * StringUtils.leftPad("bat", 5, 'z')  = "zzbat"
     * StringUtils.leftPad("bat", 1, 'z')  = "bat"
     * StringUtils.leftPad("bat", -1, 'z') = "bat"
     * </pre>
     */
    public static String leftPad(final String str, final int size, final char padChar) {
        if (str == null) {
            return null;
        }
        final int pads = size - str.length();
        if (pads <= 0) {
            return str; // returns original String when possible
        }
        if (pads > 8192) {
            return leftPad(str, size, padChar);
        }
        return repeat(padChar, pads).concat(str);
    }

    /**
     * <p> 构造指定个数的字符的字符串 </p>
     * 
     * <pre>
     * StringUtils.repeat('e', 0)  = ""
     * StringUtils.repeat('e', 3)  = "eee"
     * StringUtils.repeat('e', -2) = ""
     * </pre>
     */
    public static String repeat(final char ch, final int repeat) {
        final char[] buf = new char[repeat];
        for (int i = repeat - 1; i >= 0; i-- ) {
            buf[i] = ch;
        }
        return new String(buf);
    }

    /**
     * 字段转换成数据库键名 aaBbCc→AA_BB_CC<br> 如果参数含有_则不做转换
     * @param str
     * @author dk 2015-04-10
     * @return
     */
    public static String converStr2ClumnStr(String str) {
        if (str == null) {
            return null;
        }
        if (str.indexOf("_") > -1) {
            return str;
        }
        if (str.equals(str.toUpperCase())) {
            return str;
        }
        return str.replaceAll(" (?i)desc", " desc").replaceAll(" (?i)asc", " asc")
            // .replaceAll("^(?i)select ", "select ")
            // .replaceAll(" (?i)from ", " from ")
            // .replaceAll("^(?i)update ", " update ")
            // .replaceAll(" (?i)set ", " set ")
            // .replaceAll(" (?i)where ", " where ")
            // .replaceAll(" (?i)and ", " and ")
            // .replaceAll(" (?i)exists ", " exists ")
            // .replaceAll(" (?i)join ", " join ")
            .replaceAll("([A-Z])", "_$1").toUpperCase();
    }

    /**
     * 转换数据库键名 aa_bb_cc→aaBbCc
     * @param clumn
     * @author dk 2015-04-09
     * @return
     */
    public static String converClumnStr2Str(String clumn) {
        if (clumn == null) {
            return "";
        }
        clumn = clumn.toLowerCase();
        Matcher mat = Pattern.compile("_([a-z])").matcher(clumn);
        while (mat.find()) {
            clumn = clumn.replace("_" + mat.group(1), mat.group(1).toUpperCase());
        }
        return clumn.replaceAll("_", "");
    }

    /**
     * <p> 试用指定字符构造字符串 </p>
     * 
     * <pre>
     * StringUtils.join(null, *)         = null
     * StringUtils.join([], *)           = ""
     * StringUtils.join([null], *)       = ""
     * StringUtils.join([1, 2, 3], ";")  = "1;2;3"
     * StringUtils.join([1, 2, 3], null) = "123"
     * </pre>
     */
    public static <T> String join(final T[] array, String separator) {
        separator = nvl(separator);
        if (array == null) {
            return null;
        }
        final int noOfItems = array.length;
        if (noOfItems <= 0) {
            return "";
        }
        final StringBuilder buf = new StringBuilder(noOfItems * 16);
        for (int i = 0; i < noOfItems; i++ ) {
            if (i > 0) {
                buf.append(separator);
            }
            buf.append(array[i]);
        }
        return buf.toString();
    }

    /**
     * 将数组转换成list
     * @param array
     * @return
     */
    public static <T> List<T> arrayToList(final T[] array) {
        return Arrays.asList(array);
    }

    /**
     * 将list转换成数组
     * @param list
     * @return
     */
    public static <T> Object[] listToArray(final Collection<T> list) {
        return list.toArray();
    }

    /**
     * 向集合中添加元素
     * @param array
     * @param separator
     * @return
     */
    public static <T> String join(final Collection<T> array, String separator) {
        return join(listToArray(array), separator);
    }

    /**
     * 向集合中添加元素
     * @param array
     * @param separator
     * @return
     */
    public static <T> String join(final Collection<T> array, char separator) {
        return join(listToArray(array), String.valueOf(separator));
    }

    /**
     * 根据分割符分割字符串成数组
     * @param value
     * @param regex
     * @return
     */
    public static String[] split(String value, String regex) {
        return value == null ? null : value.split(regex);
    }

    /**
     * 将用户名 隐藏中间3个字
     * @param username
     * @return
     */
    public static String hideUserName(String username) {
        int len = username.length();
        String temp = "";
        if (len <= 4) {
            String first = username.substring(0, 1);
            String str = username.substring(1);
            temp = first + "***";// username.replace(str, "**");
        } else {
            String start = username.substring(0, 2);
            String end = username.substring(username.length() - 2, username.length());
            temp = start;
            for (int i = 3; i < username.length() - 1; i++ ) {
                temp += "*";
            }
            temp = temp + end;
        }

        return temp;
    }

    /**
     * 获取字符串的MD5数据(32位)字母大写
     * @param plainText 要加密的字符串
     * @return 加密后的字符串
     */
    public static String getMd5Upper(String plainText) {
        return getMd5(plainText).toUpperCase();
    }

    /**
     * 获取字符串的MD5数据(32位)字母小写
     * @param plainText 要加密的字符串
     * @return 加密后的字符串
     */
    public static String getMd5(String plainText) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(plainText.getBytes());
            byte b[] = md.digest();

            int i;

            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++ ) {
                i = b[offset];
                if (i < 0) i += 256;
                if (i < 16) buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            return buf.toString();
        } catch (NoSuchAlgorithmException e) {
            LOGGER.error(e.getMessage(), e);
            return null;
        }

    }

    /***
     * 获取唯一的UUID字符串
     * @return UUID字符串 如 : fbe1b750a9f5497681bcc3dcabfa0af3
     */
    public static String getRandomUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 获取多位随机数
     * @param size 位数
     * @return
     */
    public static String getRandomBySize(int size) {
        String result = "";
        Random random = new Random();
        for (int i = 0; i < size; i++ ) {
            result += random.nextInt(10);
        }
        return result;
    }

    /**
     * 判断加密前后两个字符串结果是否相同
     * @param password 未加密的字符串
     * @param md5PwdStr md5加密后的字符串
     * @return 相同返回 true 否则返回false
     */
    public static boolean checkPassword(String password, String md5PwdStr) {
        String s = getMd5(password);
        return s.equals(md5PwdStr);
    }

    /**
     * 返回当天日期的{@link #FORMAT_DATE}格式.
     */
    public static String getDayStr() {
        return new SimpleDateFormat(FORMAT_DATE).format(new Date());
    }

    /**
     * 返回当天日期的{@link Timestamp}格式.
     */
    public static Timestamp getDayTimestamp() {
        return new Timestamp(new Date().getTime());
    }

    /**
     * 返回当天的年月{@link #FORMAT_DATE_YEARMONTH}格式.
     */
    public static String getYearMonth(Date date) {
        return new SimpleDateFormat(FORMAT_DATE_YEARMONTH).format(date);
    }

    /**
     * 返回当天的年月的上一月{@link #FORMAT_DATE_YEARMONTH}格式 , 如果日期出错则返回null.
     */
    public static String getBeforeYearMonth(String yearMonth) {
        try {
            SimpleDateFormat df = new SimpleDateFormat(FORMAT_DATE_YEARMONTH);
            java.util.Date date = df.parse(yearMonth);
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) - 1);
            return getYearMonth(cal.getTime());
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 返回{@code date}日期的{@link #FORMAT_DATE}格式.
     */
    public static String getDayStr(Date date) {
        return new SimpleDateFormat(FORMAT_DATE).format(date);
    }

    /**
     * 取当天的第1秒的时间.
     */
    public static Date getBeginOfDay(Date date) {
        Calendar cBegin = Calendar.getInstance();
        cBegin.setTime(date);
        cBegin.set(Calendar.HOUR_OF_DAY, 0);
        cBegin.set(Calendar.MINUTE, 0);
        cBegin.set(Calendar.SECOND, 0);
        cBegin.set(Calendar.MILLISECOND, 0);
        return cBegin.getTime();
    }

    /**
     * 取当天的最后一秒的时间.
     */
    public static Date getEndOfDay(Date date) {
        Calendar cEnd = Calendar.getInstance();
        cEnd.setTime(date);
        cEnd.set(Calendar.HOUR_OF_DAY, 23);
        cEnd.set(Calendar.MINUTE, 59);
        cEnd.set(Calendar.SECOND, 59);
        cEnd.set(Calendar.MILLISECOND, 999);
        return cEnd.getTime();
    }

    /**
     * 返回当天时间的{@link #FORMAT_TIME}格式.
     */
    public static String getTimeStr() {
        return new SimpleDateFormat(FORMAT_TIME).format(new Date());
    }

    /**
     * 返回{@code date}时间的{@link #FORMAT_TIME}格式.
     */
    public static String getTimeStr(Date date) {
        return new SimpleDateFormat(FORMAT_TIME).format(date);
    }

    public static void main(String[] args) {
        System.out.println(getMd5("hell").length());
    }

    /**
     * 当前日期转换成yyyyMMddHHmmssSSS格式.
     */
    public static String getDateStr() {
        Date time = new Date();
        String timeString = new SimpleDateFormat(FORMAT_DATETIME_ALL_SSS).format(time);
        return timeString;
    }

    /**
     * 返回当前日期的 yyyy年MM月dd日.
     */
    public static String getDateStringChinese() {
        Date time = new Date();
        String timeString = new SimpleDateFormat("yyyy年MM月dd日").format(time);
        return timeString;
    }

    /**
     * 将长时间格式时间转换为字符串 yyyy-MM-dd HH:mm
     */
    public static String dateToStrNoSecond(Date dateDate) {
        String dateString = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(dateDate);
        return dateString;
    }

    /**
     * 取日期的字符串 {@link #FORMAT_DATA_PDF_}.
     */
    public static String getPdfDate() {
        return new SimpleDateFormat(FORMAT_DATA_PDF).format(new Date());
    }

    /**
     * 获得昨天的日期.
     */
    public static String getDateStr(Date day) {
        return new SimpleDateFormat(FORMAT_DATE).format(day);
    }

    /**
     * 将字符串解析成日期.
     */
    public static Date getDate(String dateStr, String formate) {
        try {
            return new SimpleDateFormat(formate).parse(dateStr);
        } catch (ParseException e) {
            LOGGER.error("解析日期出错");
        }
        return null;
    }

    /**
     * 将字符串解析成日期.
     */
    public static Date getDateFromStr(String dateStr) {
        try {
            return new SimpleDateFormat(FORMAT_DATE).parse(dateStr);
        } catch (ParseException e) {
            LOGGER.error("解析日期出错");
        }
        return null;
    }

    /**
     * 获得昨天的日期.
     */
    public static Date getLastDayDate() {
        String lastDay = getDownloadDateString()[1];
        try {
            return new SimpleDateFormat(FORMAT_DATE).parse(lastDay);
        } catch (ParseException e) {
            LOGGER.error("解析日期出错");
        }
        return null;
    }

    /**
     * 获得昨天和今天的日期.
     */
    public static String[] getDownloadDateString() {
        String string[] = new String[2];
        Calendar cal = Calendar.getInstance();
        String yesterday = new SimpleDateFormat(FORMAT_DATE).format(cal.getTime());
        string[0] = yesterday;
        cal.add(Calendar.DAY_OF_MONTH, -1);
        yesterday = new SimpleDateFormat(FORMAT_DATE).format(cal.getTime());
        string[1] = yesterday;
        return string;
    }

    /**
     * 取日期的字符串 yyyyMMddHHmmssSSS.
     */
    public static String getDateTimes() {
        return new SimpleDateFormat(FORMAT_DATETIME_ALL_SSS).format(new Date());
    }

    /**
     * 取date的年与日期的字符串,返回格式为2013/002/.
     * @param date 计算的日期.
     */
    public static String getYearDaysStr(Date date) {
        return getDayOfYear(date);
    }

    /**
     * 取date的年与日期的字符串,返回格式为2013/002/.
     * @param date 计算的日期.
     * @param dayPos 日期的偏移，+为今天以后的，－为今天之前的偏移量
     */
    public static String getYearDaysStr(Date date, int dayPos) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR) + dayPos);
        return getDayOfYear(c.getTime());
    }

    /**
     * 取date所在年份的第几天，长度为3位，不足的前补0.
     * @param date 计算的天数
     */
    private static String getDayOfYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        String dayOfYear = c.get(Calendar.DAY_OF_YEAR) + "";
        while (dayOfYear.length() < 3) {
            dayOfYear = "0" + dayOfYear;
        }
        return c.get(Calendar.YEAR) + "/" + dayOfYear + "/";
    }

    /**
     * 格式化Calendar. 格式 yyyy-M-d
     */
    public static String formatCalendar(Calendar calendar) {
        if (calendar == null) {
            return "";
        }
        return new SimpleDateFormat(FORMAT_DATE_SIMPLE).format(calendar.getTime());
    }

    /**
     * 格式 yyyy-M-d HH:mm:ss
     */
    public static String formatDateTime(Date d) {
        if (d == null) {
            return "";
        }
        return new SimpleDateFormat(FORMAT_DATETIME_SIMPLE).format(d);
    }

    /**
     * 格式 yyyy-M-d FORMAT_DATE_SIMPLE.
     */
    public static String formatDate(Date d) {
        if (d == null) {
            return "";
        }
        return new SimpleDateFormat(FORMAT_DATE_SIMPLE).format(d);
    }

    /**
     * 格式化时间.
     */
    public static String formatTime(Date d) {
        if (d == null) {
            return "";
        }
        return new SimpleDateFormat(FORMAT_TIME).format(d);
    }

    /**
     * 格式化整数型日期.
     */
    public static String formatIntDate(Integer intDate) {
        if (intDate == null) {
            return "";
        }
        Calendar c = newCalendar(intDate);
        return formatCalendar(c);
    }

    /**
     * 根据指定格式化来格式日期.
     * @param date 待格式化的日期.
     * @param pattern 格式化样式或分格,如yyMMddHHmmss
     * @return 字符串型日期.
     */
    public static String formatDate(Date date, String pattern) {
        if (date == null) {
            return "";
        }
        if (null == pattern || "".equals(pattern.trim())) {
            return formatDate(date);
        }
        SimpleDateFormat simpleDateFormat = null;
        try {
            simpleDateFormat = new SimpleDateFormat(pattern);
        } catch (Exception e) {
            e.printStackTrace();
            return formatDate(date);
        }
        return simpleDateFormat.format(date);
    }

    /**
     * 取得Integer型的当前日期.
     */
    public static Integer getIntNow() {
        return getIntDate(getNow());
    }

    /**
     * 取得Integer型的当前日期.
     */
    public static Integer getIntToday() {
        return getIntDate(getNow());
    }

    /**
     * 取得Integer型的当前年份.
     */
    public static Integer getIntYearNow() {
        Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        return year;
    }

    /**
     * 取得Integer型的当前月份.
     */
    public static Integer getIntMonthNow() {
        Calendar c = Calendar.getInstance();
        int month = c.get(Calendar.MONTH) + 1;
        return month;
    }

    /**
     * 根据年月日获取整型日期.
     */
    public static Integer getIntDate(int year, int month, int day) {
        return getIntDate(newCalendar(year, month, day));
    }

    /**
     * 某年月的第一天.
     */
    public static Integer getFirstDayOfMonth(int year, int month) {
        return getIntDate(newCalendar(year, month, 1));
    }

    /**
     * 某年月的第一天.
     */
    public static Integer getFirstDayOfThisMonth() {
        Integer year = getIntYearNow();
        Integer month = getIntMonthNow();
        return getIntDate(newCalendar(year, month, 1));
    }

    /**
     * 某年月的第一天.
     */
    public static Integer getFistDayOfMonth(Date date) {
        Integer intDate = getIntDate(date);
        int year = intDate / 10000;
        int month = intDate % 10000 / 100;
        return getIntDate(newCalendar(year, month, 1));
    }

    /**
     * 某年月的最后一天.
     */
    public static Integer getLastDayOfMonth(int year, int month) {
        return intDateSub(getIntDate(newCalendar(year, month + 1, 1)), 1);
    }

    /**
     * 根据Calendar获取整型年份.
     */
    public static Integer getIntYear(Calendar c) {
        int year = c.get(Calendar.YEAR);
        return year;
    }

    /**
     * 根据Calendar获取整型日期.
     */
    public static Integer getIntDate(Calendar c) {
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH) + 1;
        int day = c.get(Calendar.DAY_OF_MONTH);
        return year * 10000 + month * 100 + day;
    }

    /**
     * 根据Date获取整型年份.
     */
    public static Integer getIntYear(Date d) {
        if (d == null) {
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return getIntYear(c);
    }

    /**
     * 根据Date获取整型日期.
     */
    public static Integer getIntDate(Date d) {
        if (d == null) {
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return getIntDate(c);
    }

    /**
     * 判断今天是今年的第几天.
     */
    public static String getSysString() {
        // 获取系统时间
        Date date = new Date();
        // %tj表示一年中的第几天
        String strDate = String.format("%tj", date);
        return strDate;
    }

    /**
     * 判断该日是今年的第几天.
     */
    public static String getSysString(String dateString) {
        // 设置时间
        Date date = strToDate(dateString);
        // %tj表示一年中的第几天
        String strDate = String.format("%tj", date);
        return strDate;
    }

    /**
     * 判断给定日期是今年的第几天.
     */
    public static String getSysString(Date date) {
        // %tj表示一年中的第几天
        String strDate = String.format("%tj", date);
        return strDate;
    }

    /**
     * 根据Integer获取Date日期.
     */
    public static Date getDate(Integer n) {
        if (n == null) {
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.set(n / 10000, n / 100 % 100 - 1, n % 100);
        return c.getTime();
    }

    public static Date getDate(String date) {
        if (date == null || date.length() == 0) {
            return null;
        }

        try {
            if (date.contains("/")) {
                date = date.replaceAll("/", "-");
            }
            return new SimpleDateFormat(FORMAT_DATE).parse(date);
        } catch (ParseException e) {
            LOGGER.error("解析[" + date + "]错误！", e);
            return null;
        }
    }

    /**
     * 根据年份Integer获取Date日期.
     */
    public static Date getFirstDayOfYear(Integer year) {
        if (year == null) {
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.set(year, 1, 1);
        return c.getTime();
    }

    /**
     * 根据年月日生成Calendar.
     */
    public static Calendar newCalendar(int year, int month, int day) {
        Calendar ret = Calendar.getInstance();
        if (year < 100) {
            year = 2000 + year;
        }
        ret.set(year, month - 1, day);
        return ret;
    }

    /**
     * 根据整型日期生成Calendar.
     */
    public static Calendar newCalendar(int date) {
        int year = date / 10000;
        int month = (date % 10000) / 100;
        int day = date % 100;

        Calendar ret = Calendar.getInstance();
        ret.set(year, month - 1, day);
        return ret;
    }

    /**
     * 取得Date型的当前日期.
     */
    public static Date getNow() {
        return new Date();
    }

    /**
     * 取得Date型的当前日期.
     */
    public static Date getToday() {
        return getDate(getIntToday());
    }

    /**
     * 整数型日期的加法.
     */
    public static Integer intDateAdd(int date, int days) {
        int year = date / 10000;
        int month = (date % 10000) / 100;
        int day = date % 100;

        day += days;

        return getIntDate(year, month, day);
    }

    /**
     * 整数型日期的减法.
     */
    public static Integer intDateSub(int date, int days) {
        return intDateAdd(date, -days);
    }

    /**
     * 计算两个整型日期之间的天数.
     */
    public static Integer daysBetweenDate(Integer startDate, Integer endDate) {
        if (startDate == null || endDate == null) {
            return null;
        }
        Calendar c1 = newCalendar(startDate);
        Calendar c2 = newCalendar(endDate);

        Long lg = (c2.getTimeInMillis() - c1.getTimeInMillis()) / 1000 / 60 / 60 / 24;
        return lg.intValue();
    }

    /**
     * 计算两个整型日期之间的天数.
     */
    public static Integer daysBetweenDate(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return null;
        }
        Long interval = endDate.getTime() - startDate.getTime();
        interval = interval / (24 * 60 * 60 * 1000);
        return interval.intValue();
    }

    /**
     * 计算两个日期之间间隔的时间,*D*H*M*S.
     */
    public static String calTwoDays(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return null;
        }
        Long interval = endDate.getTime() - startDate.getTime();
        Long days = interval / (24 * 60 * 60 * 1000);
        Long hour = interval / (60 * 60 * 1000) % 24;
        Long min = interval / (60 * 1000) % (24 * 60);
        Long sencond = interval / (1000) % (24 * 60 * 60);
        return new StringBuffer().append(days + "D" + hour + "H" + min + "M" + sencond + "S").toString();
    }

    /**
     * 根据calendar产生字符串型日期 eg:20080707.
     */
    public static String getStringDate(Date d) {
        if (d == null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        return sdf.format(d);
    }

    public static String getFormatStringDate(Date d) {
        if (d == null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        return sdf.format(d);
    }

    /**
     * 获得所在星期的第一天.
     */
    public static Date getFirstDateByWeek(Date date) {

        Calendar now = Calendar.getInstance();
        now.setTime(date);
        int today = now.get(Calendar.DAY_OF_WEEK);
        int firstDayOfWeek = now.get(Calendar.DATE) + 2 - today; // 星期一
        now.set(Calendar.DATE, firstDayOfWeek);
        return now.getTime();
    }

    /**
     * 获得所在星期的最后一天.
     */
    public static Date getLastDateByWeek(Date date) {

        Calendar now = Calendar.getInstance();
        now.setTime(date);
        int today = now.get(Calendar.DAY_OF_WEEK);
        int firstDayOfWeek = now.get(Calendar.DATE) + 2 - today; // 星期一
        int lastDayOfWeek = firstDayOfWeek + 6; // 星期日
        now.set(Calendar.DATE, lastDayOfWeek);
        return now.getTime();
    }

    /**
     * 获得所在月份的最后一天.
     * @param 当前月份所在的时间
     * @return 月份的最后一天
     */
    public static Date getLastDateByMonth(Date date) {
        Calendar now = Calendar.getInstance();
        now.setTime(date);
        now.set(Calendar.MONTH, now.get(Calendar.MONTH) + 1);
        now.set(Calendar.DATE, 1);
        now.set(Calendar.DATE, now.get(Calendar.DATE) - 1);
        now.set(Calendar.HOUR, 11);
        now.set(Calendar.MINUTE, 59);
        now.set(Calendar.SECOND, 59);
        return now.getTime();
    }

    /**
     * 获得所在月份的第一天.
     * @param 当前月份所在的时间
     * @return 月份的第一天
     */
    public static Date getFirstDateByMonth(Date date) {

        Calendar now = Calendar.getInstance();
        now.setTime(date);
        now.set(Calendar.DATE, 0);
        now.set(Calendar.HOUR, 12);
        now.set(Calendar.MINUTE, 0);
        now.set(Calendar.SECOND, 0);
        return now.getTime();
    }

    /**
     * 获取现在时间.
     * @return 返回时间类型 yyyy-MM-dd HH:mm:ss
     */
    public static Date getNowDate() {
        return java.sql.Timestamp.valueOf(new SimpleDateFormat(FORMAT_DATETIME).format(new Date()));
    }

    /**
     * 获取现在时间.
     * @return返回短时间格式 yyyy-MM-dd
     */
    public static Date getNowDateShort() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_DATE);
        String dateString = formatter.format(currentTime);
        ParsePosition pos = new ParsePosition(8);
        Date currentTime2 = formatter.parse(dateString, pos);
        return currentTime2;
    }

    /**
     * 获取现在时间.
     * @return返回字符串格式 yyyy-MM-dd HH:mm:ss
     */
    public static String getStringDate() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_DATETIME);
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    /**
     * 获取现在时间.
     * @return 返回短时间字符串格式yyyy-MM-dd
     */
    public static String getStringDateShort() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_DATE);
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    /**
     * 获取时间 小时:分;秒 HH:mm:ss.
     * @return
     */
    public static String getTimeShort() {
        SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
        Date currentTime = new Date();
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    /**
     * 将长时间格式字符串转换为时间 yyyy-MM-dd HH:mm:ss.
     * @param strDate
     * @return
     */
    public static Date strToDateLong(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_DATETIME);
        ParsePosition pos = new ParsePosition(0);
        if (strDate != null) {
            Date strtodate = formatter.parse(strDate, pos);
            return strtodate;
        }
        return null;
    }

    /**
     * 将长时间格式时间转换为字符串 yyyy-MM-dd HH:mm:ss.
     * @param dateDate
     * @return
     */
    public static String dateToStrLong(java.util.Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_DATETIME);
        String dateString = formatter.format(dateDate);
        return dateString;
    }

    /**
     * 将短时间格式时间转换为字符串 yyyy-MM-dd.
     * @param dateDate
     * @param k
     * @return
     */
    public static String dateToStr(java.util.Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_DATE);
        // public static final String FORMAT_DATE = "yyyy-MM-dd";
        // FORMAT_DATE_FORMAT
        String dateString = formatter.format(dateDate);
        return dateString;
    }

    /**
     * 将短时间格式时间转换为字符串 yyyy-MM-dd HH.
     */
    public static String dateToStrWithH(java.util.Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_DATE_HH);
        // public static final String FORMAT_DATE = "yyyy-MM-dd";
        // FORMAT_DATE_FORMAT
        String dateString = formatter.format(dateDate);
        return dateString;
    }

    /**
     * 将短时间格式时间转换为字符串 yyyy.MM.dd.
     */
    public static String dateToStrDot(java.util.Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_DATE_DOT);
        String dateString = formatter.format(dateDate);
        return dateString;
    }

    /**
     * 将短时间格式时间转换为字符串 yyyy.MM.dd.HH.
     */
    public static String dateToStrDotHH(java.util.Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_DATE_DOTHOUR);
        String dateString = formatter.format(dateDate);
        return dateString;
    }

    /**
     * 将短时间格式字符串转换为时间 yyyy-MM-dd.
     */
    public static Date strToDate(String strDate) {
        if (strDate == null) {
            return null;
        }
        SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_DATE);
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(strDate, pos);
        return strtodate;
    }

    /**
     * 提取一个月中的最后一天.
     */
    public static Date getLastDate(long day) {
        Date date = new Date();
        long date3hm = date.getTime() - 3600000 * 34 * day;
        Date date3hmDate = new Date(date3hm);
        return date3hmDate;
    }

    /**
     * 得到现在时间.
     * @return 字符串 yyyyMMdd HHmmss
     */
    public static String getStringToday() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd HHmmss");
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    /**
     * 得到现在小时.
     */
    public static String getHour() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_DATETIME);
        String dateString = formatter.format(currentTime);
        String hour;
        hour = dateString.substring(11, 13);
        return hour;
    }

    /**
     * 得到现在分钟.
     */
    public static String getTime() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_DATETIME);
        String dateString = formatter.format(currentTime);
        String min;
        min = dateString.substring(14, 16);
        return min;
    }

    /**
     * 根据用户传入的时间表示格式，返回当前时间的格式 如果是yyyyMMdd，注意字母y不能大写.
     * @param sformat yyyyMMddhhmmss
     * @return
     */
    public static String getUserDate(String sformat) {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(sformat);
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    /**
     * 二个小时时间间的差值,必须保证二个时间都是"HH:MM"的格式，返回字符型的分钟.
     */
    public static String getTwoHour(String st1, String st2) {
        String[] kk = null;
        String[] jj = null;
        kk = st1.split(":");
        jj = st2.split(":");
        if (Integer.parseInt(kk[0]) < Integer.parseInt(jj[0]))
            return "0";
        else {
            double y = Double.parseDouble(kk[0]) + Double.parseDouble(kk[1]) / 60 + Double.parseDouble(kk[2]);
            double u = Double.parseDouble(jj[0]) + Double.parseDouble(jj[1]) / 60 + Double.parseDouble(jj[2]);
            if ((y - u) > 0)
                return y - u + "";
            else
                return "0";
        }
    }

    /**
     * 得到二个日期间的间隔天数.
     */
    public static String getTwoDay(String sj1, String sj2) {
        SimpleDateFormat myFormatter = new SimpleDateFormat(FORMAT_DATE);
        long day = 0;
        try {
            java.util.Date date = myFormatter.parse(sj1);
            java.util.Date mydate = myFormatter.parse(sj2);
            day = (date.getTime() - mydate.getTime()) / (24 * 60 * 60 * 1000);
        } catch (Exception e) {
            return "";
        }
        return day + "";
    }

    /**
     * 得到二个日期间的间隔天数.
     */
    public static long getTwoDay(Calendar beginDate, Calendar endDate) {
        try {
            return (endDate.getTime().getTime() - beginDate.getTime().getTime()) / (24 * 60 * 60 * 1000);
        } catch (Exception e) {
            return -1;
        }
    }

    /**
     * 得到二个日期间的间隔的小时数.
     */
    public static long getTwoDayHours(Calendar beginDate, Calendar endDate) {
        try {
            return (endDate.getTime().getTime() - beginDate.getTime().getTime()) / (60 * 60 * 1000);
        } catch (Exception e) {
            return -1;
        }
    }

    /**
     * 得到二个日期间的间隔的秒.
     */
    public static long getTwoDaySecond(Date beginDate, Date endDate) {
        try {
            return (endDate.getTime() - beginDate.getTime()) / (1000);
        } catch (Exception e) {
            return -1;
        }
    }

    /**
     * 得到二个日期间的间隔的豪秒数.
     */
    public static long getTwoDayMiniSecond(Date beginDate, Date endDate) {
        try {
            return (endDate.getTime() - beginDate.getTime()) / (1000);
        } catch (Exception e) {
            return -1;
        }
    }

    /**
     * 时间前推或后推分钟,其中JJ表示分钟.
     */
    public static String getPreTime(String sj1, String jj) {
        SimpleDateFormat format = new SimpleDateFormat(FORMAT_DATETIME);
        String mydate1 = "";
        try {
            Date date1 = format.parse(sj1);
            long time = (date1.getTime() / 1000) + Integer.parseInt(jj) * 60;
            date1.setTime(time * 1000);
            mydate1 = format.format(date1);
        } catch (Exception e) {}
        return mydate1;
    }

    /**
     * 得到一个时间延后或前移几天的时间,nowdate为时间,delay为前移或后延的天数.
     */
    public static String getNextDay(String nowdate, String delay) {
        try {
            SimpleDateFormat format = new SimpleDateFormat(FORMAT_DATE);
            String mdate = "";
            Date d = strToDate(nowdate);
            long myTime = (d.getTime() / 1000) + Integer.parseInt(delay) * 24 * 60 * 60;
            d.setTime(myTime * 1000);
            mdate = format.format(d);
            return mdate;
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 判断是否润年.
     */
    public static boolean isLeapYear(String ddate) {

        /**
         * 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年 3.能被4整除同时能被100整除则不是闰年
         */
        Date d = strToDate(ddate);
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(d);
        int year = gc.get(Calendar.YEAR);
        if ((year % 400) == 0)
            return true;
        else if ((year % 4) == 0) {
            if ((year % 100) == 0)
                return false;
            else
                return true;
        } else
            return false;
    }

    /**
     * 返回美国时间格式 26 Apr 2006.
     */
    public static String getEDate(String str) {
        SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_DATE);
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(str, pos);
        String j = strtodate.toString();
        String[] k = j.split(" ");
        return k[2] + k[1].toUpperCase() + k[5].substring(2, 4);
    }

    /**
     * 获取一个月的最后一天.
     */
    public static String getEndDateOfMonth(String dat) {// yyyy-MM-dd
        String str = dat.substring(0, 8);
        String month = dat.substring(5, 7);
        int mon = Integer.parseInt(month);
        if (mon == 1 || mon == 3 || mon == 5 || mon == 7 || mon == 8 || mon == 10 || mon == 12) {
            str += "31";
        } else if (mon == 4 || mon == 6 || mon == 9 || mon == 11) {
            str += "30";
        } else {
            if (isLeapYear(dat)) {
                str += "29";
            } else {
                str += "28";
            }
        }
        return str;
    }

    /**
     * 判断二个时间是否在同一个周.
     */
    public static boolean isSameWeekDates(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(date1);
        cal2.setTime(date2);
        int subYear = cal1.get(Calendar.YEAR) - cal2.get(Calendar.YEAR);
        if (0 == subYear) {
            if (cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR)) return true;
        } else if (1 == subYear && 11 == cal2.get(Calendar.MONTH)) {
            // 如果12月的最后一周横跨来年第一周的话则最后一周即算做来年的第一周
            if (cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR)) return true;
        } else if (-1 == subYear && 11 == cal1.get(Calendar.MONTH)) {
            if (cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR)) return true;
        }
        return false;
    }

    /**
     * 产生周序列,即得到当前时间所在的年度是第几周.
     */
    public static String getSeqWeek() {
        Calendar c = Calendar.getInstance(Locale.CHINA);
        String week = Integer.toString(c.get(Calendar.WEEK_OF_YEAR));
        if (week.length() == 1) week = "0" + week;
        String year = Integer.toString(c.get(Calendar.YEAR));
        return year + week;
    }

    /**
     * 获得一个日期所在的周的星期几的日期，如要找出2002年2月3日所在周的星期一是几号.
     */
    public static String getWeek(String sdate, String num) {
        // 再转换为时间
        Date dd = strToDate(sdate);
        Calendar c = Calendar.getInstance();
        c.setTime(dd);
        if (num.equals("1")) // 返回星期一所在的日期
            c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        else if (num.equals("2")) // 返回星期二所在的日期
            c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
        else if (num.equals("3")) // 返回星期三所在的日期
            c.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
        else if (num.equals("4")) // 返回星期四所在的日期
            c.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
        else if (num.equals("5")) // 返回星期五所在的日期
            c.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
        else if (num.equals("6")) // 返回星期六所在的日期
            c.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
        else if (num.equals("0")) // 返回星期日所在的日期
            c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return new SimpleDateFormat(FORMAT_DATE).format(c.getTime());
    }

    /**
     * 根据一个日期，返回是星期几的字符串.
     */
    public static String getWeek(String sdate) {
        // 再转换为时间
        Date date = strToDate(sdate);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        // int hour=c.get(Calendar.DAY_OF_WEEK);
        // hour中存的就是星期几了，其范围 1~7
        // 1=星期日 7=星期六，其他类推
        return new SimpleDateFormat("EEEE").format(c.getTime());
    }

    /**
     * 两个时间之间的天数.
     */
    public static long getDays(String date1, String date2) {
        if (date1 == null || date1.equals("")) return 0;
        if (date2 == null || date2.equals("")) return 0;
        // 转换为标准时间
        SimpleDateFormat myFormatter = new SimpleDateFormat(FORMAT_DATE);
        java.util.Date date = null;
        java.util.Date mydate = null;
        try {
            date = myFormatter.parse(date1);
            mydate = myFormatter.parse(date2);
        } catch (Exception e) {}
        long day = (date.getTime() - mydate.getTime()) / (24 * 60 * 60 * 1000);
        return day;
    }

    /**
     * 形成如下的日历 ， 根据传入的一个时间返回一个结构 星期日 星期一 星期二 星期三 星期四 星期五 星期六 下面是当月的各个时间 此函数返回该日历第一行星期日所在的日期.
     */
    public static String getNowMonth(String sdate) {
        // 取该时间所在月的一号
        sdate = sdate.substring(0, 8) + "01";

        // 得到这个月的1号是星期几
        Date date = strToDate(sdate);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int u = c.get(Calendar.DAY_OF_WEEK);
        String newday = getNextDay(sdate, (1 - u) + "");
        return newday;
    }

    /**
     * 取得数据库主键 生成格式为yyyymmddhhmmss+k位随机数.
     * @param k 表示是取几位随机数，可以自己定
     */

    public static String getNo(int k) {

        return getUserDate("yyyyMMddhhmmss") + getRandom(k);
    }

    /**
     * 返回一个随机数.
     */
    public static String getRandom(int i) {
        Random jjj = new Random();
        // int suiJiShu = jjj.nextInt(9);
        if (i == 0) return "";
        String jj = "";
        for (int k = 0; k < i; k++ ) {
            jj = jj + jjj.nextInt(9);
        }
        return jj;
    }

    /**
     * 判断是否是一定格式正确的日期.
     */
    public static boolean rightDate(String date) {
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATETIME);
        if (date == null) return false;
        if (date.length() > 10) {
            sdf = new SimpleDateFormat(FORMAT_DATETIME);
        } else {
            sdf = new SimpleDateFormat(FORMAT_DATE);
        }
        try {
            sdf.parse(date);
        } catch (ParseException pe) {
            return false;
        }
        return true;
    }

    /**
     * 将formBean 里的字符时间(yyyy-MM-dd) 转换成Date类型.
     */
    public static Date formBeanDateToPODate(String formDate) {
        try {
            if (null != formDate && !"".equals(formDate.trim())) {

                LOGGER.debug("---------formdate:" + formDate);
                return java.sql.Date.valueOf(formDate);

            }
        } catch (Exception e) {
            System.out.println("DateUtils:时间转换异常");
            return new Date();
        }
        return null;
    }

    /**
     * 获取当前日期的字符串，格式为 yyyyMMddHHmmss
     * @return
     */
    public static String getDateString() {
        DateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        Date time = new Date();
        String timeString = format.format(time);
        return timeString;
    }

    /**
     * 将天数转换成日期.
     * @param tianshu 天份
     * @param nianfen 年份
     * @return 日期
     */
    public static Date tianshuBecomeDate(int tianshu, int nianfen) {

        Calendar calendar = new GregorianCalendar(nianfen, 0, 0, 0, 0, 0);
        calendar.add(Calendar.DATE, tianshu);
        return calendar.getTime();
    }

    /**
     * 将天数，年份转化为 yyyyMMdd String.
     * @param tianshu day of year
     * @param nianfen year
     * @return
     */
    public static String tianshuBecomeDateString(int tianshu, int nianfen) {
        Date date = tianshuBecomeDate(tianshu, nianfen);
        return new SimpleDateFormat("yyyyMMdd").format(date);
    }

    /**
     * 将天数，年份转化为 yyyyMMdd String.
     * @param tianshu day of year
     * @param nianfen year
     * @return
     */
    public static String dayOfYearToDateString(String tianshu, String nianfen) {
        int day = Integer.parseInt(tianshu);
        int year = Integer.parseInt(nianfen);
        return tianshuBecomeDateString(day, year);
    }

    /**
     * yyyyMMddhhmm 变为Date类型.
     * @param dateTime yyyyMMddhhmm
     * @return
     */
    public static Date dateTimeStringtoDateTime(String dateTime) {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmm");
        Date date = null;
        try {
            date = format.parse(dateTime);
        } catch (ParseException e) {
            return null;
        }
        return date;
    }

    /**
     * Date 类型转为 yyyy String.
     * @param date
     * @return yyyy String
     */
    public static String dateToYearString(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy");
        return format.format(date);
    }

    /**
     * Date 类型转为 day of year String.
     * @param date
     * @return day of year
     */
    public static String dateToDayOfYear(Date date) {
        Calendar can = Calendar.getInstance();
        can.setTime(date);
        if (can.get(Calendar.DAY_OF_YEAR) / 10 == 0) // example 006
            return "00" + Integer.toString(can.get(Calendar.DAY_OF_YEAR));
        if (can.get(Calendar.DAY_OF_YEAR) / 100 == 0) // example 017
            return "0" + Integer.toString(can.get(Calendar.DAY_OF_YEAR));
        else
            return Integer.toString(can.get(Calendar.DAY_OF_YEAR));
    }

    /**
     * 将日期按指定格式解析 .
     * @param date 日期
     * @param formate 字符串.
     * @return 返回解析后的字符串
     */
    public static String dateToString(Date date, String formate) {
        return new SimpleDateFormat(formate).format(date);
    }

    /**
     * yyyyMMdd 变为Date类型.
     * @param dateString yyyyMMdd
     * @return Date Type
     */
    public static Date dataStringtoDate(String dateString) {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        Date date = null;
        try {
            date = format.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * date 在5-10月份间 返回 1 ： 夏季 其他时间返回 0 ： 冬季.
     * @param date
     * @return
     */
    public static int getSeasonCode(Date date) {
        DateFormat df = new SimpleDateFormat(FORMAT_DATE);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int year = cal.get(Calendar.YEAR);
        try {
            Date date1 = df.parse(year + "-05-01");
            Date date2 = df.parse(year + "-10-01");
            if (date.after(date1) && date.before(date2))
                return 1;
            else
                return 0;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * Date to yyyy-MM-dd HH:mm:ss.
     * @param date
     * @return
     */
    public static String datetoDateString(Date date) {
        SimpleDateFormat df = new SimpleDateFormat(FORMAT_DATETIME);
        return df.format(date);
    }

    /**
     * yyyyMMdd 变为Date类型.
     * @param dateString yyyy-MM-dd
     * @return Date Type
     */
    public static Date stringToDateYMD(String dateString) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = format.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 字符串转化成时间类型的方法(形式为：YYYYMMDD h24:mi:ss) 字符串的格式一定要和上面PATTERN的格式一样
     * @param datetime String
     * @return Date
     */
    public static Date stringToDate(String datetime) {
        String pattern = "YYYYMMDD h24:mi:ss";
        if (null != datetime) {
            SimpleDateFormat format = new SimpleDateFormat(pattern);

            try {
                return format.parse(datetime.trim());
            } catch (ParseException e) {
                LOGGER.error("stringToDate转换失败", e.getMessage());
            }
        }
        return null;
    }

    /**
     * 字符串转换成long类型数据.
     */
    public static Long getDateTimeToNum(String dateTimeString) {
        try {
            if (StringUtils.isBlank(dateTimeString)) {
                return null;
            }
            return stringToDate(dateTimeString, FORMAT_DATETIME).getTime();
        } catch (Exception e) {
            LOGGER.error("parse date {} to Long time error {}", dateTimeString, e);
            return null;
        }
    }

    /**
     * 解析失败返回 null.
     */
    public static Date stringToDate(String dateString, String formatString) {
        SimpleDateFormat localSimpleDateFormat = new SimpleDateFormat(formatString);
        localSimpleDateFormat.setLenient(false);
        try {
            return localSimpleDateFormat.parse(dateString);
        } catch (ParseException e) {
            LOGGER.error("解析日期字符串 {}  出错 {}", dateString, e);
            return null;
        }
    }

    /**
     * EG : 2016年1月14日 .
     */
    public static String getChineseDate(Calendar calendar) {
        int i = calendar.get(1);
        int j = calendar.get(2);
        int k = calendar.get(5);
        StringBuilder sb = new StringBuilder();
        sb.append(i);
        sb.append("年");
        sb.append(j + 1);
        sb.append("月");
        sb.append(k);
        sb.append("日");
        return sb.toString();
    }

    /**
     * 根据日期返回是星期几,中文.
     */
    public static String getWeekStr(String sdate) {
        String str = "";
        str = getWeek(sdate);
        if ("1".equals(str)) {
            str = "星期日";
        } else if ("2".equals(str)) {
            str = "星期一";
        } else if ("3".equals(str)) {
            str = "星期二";
        } else if ("4".equals(str)) {
            str = "星期三";
        } else if ("5".equals(str)) {
            str = "星期四";
        } else if ("6".equals(str)) {
            str = "星期五";
        } else if ("7".equals(str)) {
            str = "星期六";
        }
        return str;
    }

    /**
     * eg : 星期四.
     */
    public static String getChineseWeekday(Calendar calendar) {
        String chinessWeekDay = "";
        switch (calendar.get(7)) {
            case 2:
                chinessWeekDay = "星期一";
                break;
            case 3:
                chinessWeekDay = "星期二";
                break;
            case 4:
                chinessWeekDay = "星期三";
                break;
            case 5:
                chinessWeekDay = "星期四";
                break;
            case 6:
                chinessWeekDay = "星期五";
                break;
            case 7:
                chinessWeekDay = "星期六";
                break;
            case 1:
                chinessWeekDay = "星期日";
                break;
            default:
                chinessWeekDay = "未知";
                break;
        }
        return chinessWeekDay;
    }

    /**
     * 不改变图片尺寸对图片的大小进行压缩
     * @param file jpg文件对象
     * @throws IOException
     */
    public static void compressJPG(File file)
        throws IOException {
        BufferedImage bufferedImage = ImageIO.read(file);
        BufferedImage temp = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
        temp.getGraphics().drawImage(bufferedImage, 0, 0, null);
        FileOutputStream out = new FileOutputStream(file);
        ImageIO.write(bufferedImage, "jpg", out);
        out.close();
    }

    /**
     * 不改变图片尺寸对图片的大小进行压缩
     * @param in 原文件
     * @param out 生成的新文件
     * @throws IOException
     */
    public static void compressJPG(File in, File out)
        throws IOException {
        BufferedImage bufferedImage = ImageIO.read(in);
        BufferedImage temp = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
        temp.getGraphics().drawImage(bufferedImage, 0, 0, null);
        FileOutputStream outs = new FileOutputStream(out);
        ImageIO.write(bufferedImage, "jpg", outs);
        outs.close();
    }
    
    public static String getFirstImgUrl(String content) {
        if(isEmpty(content)) {
            return "";
        } else {
            Element element = Jsoup.parse(content);
            Elements imgs = element.getElementsByTag("img");
            if(imgs == null || imgs.isEmpty()) {
                return "";
            } else {
                Element img = imgs.get(0);
                return img.attr("src");
            }
            //Element doc = Jsoup
           
        }
    }
}
